初识C#

C#(读作See Sharp),它是一门高级编程语言,所谓高级是指,编程分为几个阶段:

  • 机器语言
    由0和1组成,这也是机器能识别的语言,为什么机器能识别呢,简单来说1代表高电压,0代表低电压,硬件中通过高低电压控制其行为,故称其为机器语言
  • 汇编语言
    也称之为低级语言,由于0和1对于人类来说不好记,故在机器语言的基础上发展出汇编语言,汇编语言需要编译器将其转换为机器语言
  • 高级语言
    主要是相对于汇编语言而言的,它是较接近自然语言和数学公式的编程,基本脱离了机器的硬件系统,用人们更易理解的方式编写程序。编写的程序称之为源程序

C,C++,C#,Java...都是高级语言,在这里我们就是学习的C#语言

学习C# 能做什么呢?

  • 网页开发
  • 桌面软件开发
  • 游戏开发
  • 手机软件开发

我们先展示一个经典的示例:

using System; namespace ConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("hello world"); } } }

首先看 using System;
我们这个程序的功能是在屏幕打印出hello world 这句话,但是要实现这个功能,我们需要用到一些官方提供的代码库来实现这个功能,这个功能在System 这个命名空间下,就跟我们的程序一样,我们自己写的代码是在ConsoleApp 这个命名空间下,通过namespace 关键字指定我们的命名空间,using 是引入相关的命名空间的代码库,但有同学问了,我们的代码里面并没有添加任何其他文件啊,那这个 System库从哪来的呢?

解释这个问题,首先我们先来看看怎么运行我们写的这个代码,由于我们写的程序属于高级程序,机器并不能理解我们要干什么,所以,开发C# 语言的大佬还给我们提供了一个编译器(Compiler)来将我们的源代码编译成机器能理解的语言。

C#程序的编译过程,如下图

image.png

编译器将C#代码编译成DLL/EXE,DLL/EXE包含metadata(清单数据,对代码的描述)和IL(中间语言),IL(中间语言)经过CLR/JIT第二次编译才是机器码

程序的编译过程,步骤理解

  • C#源文件经过CSC.exeVisual C#程序代码编译成IL文件(这里有很多参数和开关选项,参考 http://blog.chinaunix.net/uid-20715239-id-1219110.html)),编译器编译生成程序集(exe dll

  • c#代码第一次编译为一种伪代码称微软中间语言(MSIL)和元数据,MSIL和元数据同时储存在exedll 文件中,该伪代码是独立于任何CPU 的,所以只要装有.Net FrameWork的机器均可以运行该伪代码,这就增强了c#代码的可移植性。(中间语言IL不是计算机识别语言,此IL文件不能直接被计算机使用)

  • 程序执行时,该伪代码被CLR(Commom Language RunTime)捕获,CLR激活内部的 JIT(Just in time)编译器,将伪代码编译成针对特定CPU的机器语言,当然该步还要进行类型检查等,这样程序就能在任意合理的电脑中运行,得出结果。JIT 的意思为“仅在运行时编译”,整个代码的处理过程要编译两次。(从IL文件到机器语言,这个工程是机器自动实现的

JIT(即时编辑)又是什么?

  • JIT:即时编译(Just In-Time compile),这是.NET运行可执行程序的基本方式,也就是在需要运行的时候,才将对应的IL代码编译为本机指令。传入JIT的是IL代码(第一次编译生成的代码),输出的是本机代码(机器能识别的代码),然后把结果保存起来用于将来对同一方法的调用,直到应用程序结束,大大提高了效率,所以部分加密软件通过挂钩JIT来进行IL加密,同时又保证程序正常运行。同解释执行的代码相比,JIT的执行效率要高很多。

  • JIT需要再调用这些已经被编译好并存储到代码缓存中的方法时,它不用再去解释执行了,而是可以使用代码缓存中已编译好的汇编代码。这能提升你的应用程序的执行效率,因为使用编译好的代码要比运行时去解释要快得多。(JIT将编译好的代码储存在GAC中

GAC是什么?

  • GACGlobal Assembly Cache,全局程序集缓存的简称。它解决了几个程序共享某一个程序集的问题。不必再将那个被共享的程序集拷贝到应用程序目录了,.NET应用程序在加载的时候,会首先查看全局应用程序集缓存,如果有就可以直接使用,没有再到应用程序目录进行查找。

  • GAC还有一个很重要的作用,所有被放入GAC的程序集都是强名程序集,这样可以保证相同文件名不同版本的程序集被正确的引用,这样解决了COM时代的DLL地狱问题。同时强名还可以防止程序集伪造。

Assembly(程序集)是什么?

  • Assembly是一个包含来程序的名称,版本号,自我描述,文件关联关系和文件位置等信息的一个集合。在.net框架中通过Assembly类来支持,该类位于System.Reflection下,物理位置位于:mscorlib.dll
  • 我们可以通过Assembly的信息来获取程序的类,实例等编程需要用到的信息。

编译流程

image.png

托管程序集

image.png

image.png

回到原先的话题,System库从哪来?
我们的C# 代码运行的前提是你得先安装.Net,当前我们装的是.Net7,无论你的程序是放到windowsmacoslinux,第一步就是先安装.Net SDK,它包含了所有你要用到的BCL(基础类库),我们所用的System就是其中之一,我们无需单独安装C# 编译器,因为安装.Net SDK的时候已经包含了,命令行查看

image.png

image.png

接着示例代码讲:
Program 类是默认程序启动类,其中的Main 方法是启动入口,必须是static 静态方法,这是约定,
可能你新建项目时VS 默认创建的Program文件里面没有此Program类和Main 入口函数,只有一行打印代码
Console.WriteLine("hello world");
那是因为VS给你省略了这部分代码,默认你的代码都是Main 方法中的逻辑

现在让我们手动运行写好的源代码:
打开CMD命令行工具,切换到代码文件夹路径执行一下命令,注意:按照你自己实际的参数执行

dotnet "C:\Program Files\dotnet\sdk\7.0.400-preview.23330.10\Roslyn\bincore\csc.dll" .\Program.cs /r:"C:\Program Files\dotnet\sdk\7.0.400-preview.23330.10\ref\netstandard.dll"

这时会在源代码文件夹下产生一个Program.exe 可执行文件,双击运行,直接闪现黑框,然后消失,这是因为代码很快执行完毕结束了,只需要加一行代码即可

using System; namespace ConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("hello world"); Console.ReadLine();//等待用户输入内容,以此阻挡程序结束运行 } } }

当然,平常我们编程不需要这么麻烦,一般我们都先安装IDE开发工具,我这里使用的是Visual Studio 2022预览版
下载地址
注意选择Community版本,此版本是免费的

image.png

安装工具里面我们一般只需要勾选Web开发和桌面开发就好,如有其他需求开发勾选所需模块即可,安装完开发空间,其可能会自带合适的.Net SDK,如果没有,则可以自行下载相关的SDK 版本
下载地址

image.png

image.png

新建一个控制台项目

image.png

image.png

image.png

按照提示输入项目名称和对应的.Net SDK版本,创建项目,项目名称使用英文,后续你的项目默认命名空间就是项目名

C# 的基本入门就到这里吧

鲸之声为您拼命加载中...