C#(读作“C Sharp”),C# 是面向对象的、面向组件的编程语言。

C#在2000年6月发布,使用了.NET框架作为运行环境,源于C语言系列,继承了C和C++强大功能的同时去掉了一些它们的复杂特性(例如,没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言[1]。是由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言。

C#主要应用于桌面应用程序开发、Web应用程序开发、移动应用程序开发、游戏开发、云和服务开发、数据库开发、科学计算、物联网(IoT)应用程序、人工智能(AI)应用程序等。

概述

C#是由微软公司发布的一种由C和C++衍生出来的面向对象的编程语言、运行于.NET Framework.NET Core(完全开源,跨平台)之上的高级程序设计语言2

历史发展

C#是微软公司在2000年6月发布的一种新的编程语言,主要由安德斯·海尔斯伯格(Anders Hejlsberg1 )主持开发,它是第一个面向组件的编程语言,其源码会编译成msil再运行。它借鉴了Delphi的特点,与COM(组件对象模型)是直接集成的,并且新增了许多功能及语法,而且它是微软公司.NET windows网络框架的主角3

C#最初有个更酷的名字,叫做COOL。微软从1998年12月开始了COOL项目,直到2000年2月,COOL被正式更名为C#。在1998年,Delphi语言的设计者安德斯·海尔斯伯格带领着Microsoft公司的开发团队,开始了第一个版本C#语言的设计。在2000年9月,国际信息和通信系统标准化组织为C#语言定义了一个Microsoft公司建议的标准。最终C#语言在2001年得以正式发布。

原Borland公司的首席研发设计师安德斯·海尔斯伯格在微软开发了VisualJ++ 1.0,很快Visual J++由1.1版本升级到6.0版。SUN公司认为Visual J++ 违反了Java开发平台的中立性,对微软提出了诉讼。2000年6月26日微软在奥兰多举行的“职业开发人员技术大会”(PDC2000)上,发表新的语言C#。C#语言取代了Visual J++,语言本身深受 Java、C 和 C++ 的影响4

设计目标

C#旨在设计成为一种“简单、现代、通用”,以及面向对象的程序设计语言。下面是 C# 的主要设计目标:

简单易用:C# 的设计目标之一是提供一种简单易用的语言,使开发人员能够快速上手并编写清晰明了的代码。它采用类似于其他流行编程语言的语法和概念,提供直观的语言特性和一致的编程模型。

类型安全内存安全:C# 在设计上强调类型安全和内存安全。它具有静态类型检查和类型推断机制,可以在编译时捕获大部分类型错误。此外,C# 在运行时使用垃圾回收器(Garbage Collector)来自动管理内存,减少了开发人员需要手动管理内存的工作量。

面向对象:C# 是一种面向对象的编程语言,支持封装、继承和多态等面向对象的概念。通过类、接口和继承等机制,开发人员可以组织和抽象代码,提高代码的可维护性和可重用性。

可扩展性:C# 的设计目标是支持可扩展的编程模型。它提供了丰富的库和框架,使开发人员能够构建复杂的应用程序,并轻松集成第三方库和组件。C# 还支持扩展方法、属性和索引器等特性,使开发人员能够扩展现有类型的功能。

跨平台:C# 的设计目标是实现跨平台开发。通过 .NET Core 平台,C# 应用程序可以在多个操作系统上运行,如 Windows、Linux 和 macOS。这使得开发人员能够在不同的平台上共享代码和逻辑,提高开发效率和代码重用性。

集成开发环境(IDE)支持:C# 的设计目标之一是与集成开发环境(如 Visual Studio)紧密集成。Visual Studio 提供了强大的工具和功能,使开发人员能够轻松编写、调试和部署 C# 应用程序。

C#语言及其特点

C#是的一种编程语言,具有以下突出的特点2

(1)语法简洁:不允许直接操作内存,去掉了指针操作。

(2)彻底的面向对象设计:C#具有面向对象语言所应有的一切特性:封装、继承和多态。

(3)与Web紧密结合:C#支持绝大多数的Web 标准,如 HTML、XML、SOAP 等。

(4)强大的安全性机制:可以消除软件开发中常见的错误(如语法错误),.NET提供的垃圾回收器能够帮助开发者有效地管理内存资源。

(5)兼容性: C#遵循.NET的公共语言规范(CLS),从而能够保证与其他语言开发的组件兼容。

(6)灵活的版本处理技术:C#语言本身内置了版本控制功能,因此使开发人员更加容易地开发和维护。

(7)完善的错误、异常处理机制:C#提供了完善的错误和异常处理机制,使程序在交付使用时能够更加健壮。

程序结构

C#程序结构大体可以分为注释、命名空间、类、Main方法、关键字、标识符和语句2

注释

对某行或某段代码进行说明,编译器编译程序时不执行注释的代码或文字,主要功能是方便对代码的理解与维护。

注释可以分为行注释、块注释、文档注释三种6

行注释

行注释都以“//”开头;到行结束有效。

块注释

块注释通常以“/*”开始,以“*/”结束,注释的内容放在它们之间,到遇到第一个结束分隔符有效。

说明:块注释有开始标记和结束标记;标记对之间的文本会被编译器忽略;可以跨任意多行,也可以只包括行的一部分。

文档注释

文档注释以“///”开始。文档注释包含XML文本,可以用于产生程序文档6

文档注释

类型

开始

结束

描述

单行注释

//

从开始标记到该行行尾的文本被编译器忽略

带分隔符注释

/*

*/

从开始标记到结束标记之间的文本被编译器忽略

文档注释

///

这种类型的注释包含XML文本,可以使用工具生成程序文档

如果注释的行数较少,一般使用行注释。对于连续多行的大段注释,则使用块注释。

注意:

注释可以出现在代码的任意位置,但是不能分隔关键字和标识符。

不允许嵌套注释,同一时间只能有一个注释起作用6

命名空间

命名空间

命名空间是一种用于组织和管理代码的机制。它提供了一种将相关的类型、类、接口、结构体和其他成员组织在一起的方式。通过创建命名空间,您可以避免命名冲突并提供代码的可组织性、可重用性和可维护性1

命名空间规则:

在命名空间内,每个类型名必须有别于所有其他类型。

命名空间内的类型称为命名空间的成员。

一个源文件可以包含任意数目的命名空间声明,可以顺序也可以嵌套。

命名空间不是封闭的。可以在源文件的后面或另一个源文件中再次声明。

一个命名空间可以是另一个命名空间的成员。

命名空间名称

把一组类型分组在一起并给它们一个名称,称为命名空间名称。命名空间名称应该描述命名空间的内容并和其他命名空间名称相区别6

命名空间名称可以是任何有效标识符;命名空间名称可以包括句点符号,用于把类型组织成层次。

类是一种自定义的数据类型,是 C#语言的核心和基本构成模块,包含了一组属性和方法。属性用来描述类的特征,方法用来描述类的行为。可以使用class关键字来定义一个类。

类名

类名是一种标识符,必须符合标识符的命名规则。类名要能够体现类的含义和用途。类名一般采用第一个字母大写的名词,也可以采用多个词构成的组合词2

Main方法

Main 方法是程序的入口点,C#程序中必须包含一个Main 方法,在该方法中可以创建对象和调用其他方法,一个 C#程序中只能有一个Main 方法,并且在 C#中所有的Main 方法都必须是静态的2

可以用3个修饰符修饰Main 方法,分别是 public、static 和 void。

public:说明 Main 方法是共有的,在类的外面也可以调用整个方法。

static:说明方法是一个静态方法,即这个方法属于类的本身,而不是这个类的特定对象。调用静态方法不能使用类的实例化对象,必须直接使用类名来调用。

void:此修饰符说明方法无返回值2

关键字

关键字是指在 C#语言中具有特殊意义的单词,它们被 C#设定为保留字,不能随意使用。在 C# 中,有些关键字在代码的上下文中有特殊的意义,如 get 和 set,这些被称为上下文关键字(contextual keywords)。下表列出了C# 中常见的保留关键字(Resened kevwords)和下文关键字(Contextual Keywords)7

保留关键字

abstract

as

base

bool

break

byte

case

catch

char

checked

class

const

continue

decimal

default

delegate

do

double

else

enum

event

explicit

extern

false

finally

fixed

float

for

foreach

goto

if

implicit

in

int

interface

internal

is

lock

long

namespace

new

null

object

operator

out

override

params

private

protected

public

readonly

ref

return

sbyte

sealed

short

sizeof

stackalloc

static

string

struct

switch

this

throw

true

try

typeof

uint

ulong

unchecked

unsafe

ushort

using

virtual

void

volatile

while

上下文关键字

add

allas

ascending

descending

dynamic

from

get

global

group

into

join

let

orderby

partial

remove

select

set

常用关键字注释2

abstract:可以和类、方法、属性、索引器及事件一起使用,标识一个可以扩展但不能被实体化的、必须被实现的类或方法。

as:一个转换操作符,如果转换失败,就返回null。

base:用于访问被派生类或构造中的同名成员隐藏的基类成员。

catch:定义一个代码块,在特定类型异常抛出时,执行块内代码。

checked:既是操作符又是语句,确保编译器运行时,检查整数类型操作或转换时出现的溢出。

const:标识一个可在编译时计算出来的变量值,即一经指派不可修改的值。

delegate:指定一个声明为一种委托类型。委托把方法封装为可调用实体,能在委托实体中调用。

enum:表示一个已命名常量群集的值类型。

event:允许一个类或对象提供通知的成员,他必须是委托类型。

explicit:一个定义用户自定义转换操作符的操作符,通常用来将内建类型转换为用户定义类型或反向操作,必须再转换时调用显示转换操作符。

extern:标识一个将在外部(通常不是c#语言)实现的方法。finally:定义一个代码块,在程序控制离开try代码块后执行。参见try和catch。

fixed:在一个代码块执行时,在固定内存位置为一个变量指派一个指针。

foreach:用于遍历一个群集的元素。

goto:一个跳转语句,将程序执行重定向到一个标签语句。

implicit:一个操作符,定义一个用户定义的转换操作符,通常用来将预定义类型转换为用户定义类型或反向操作,隐式转换操作符必须在转换时使用。

interface:将一个声明指定为接口类型,即实现类或构造必须遵循的合同。

internal:一个访问修饰符。

namespace:定义一个逻辑组的类型和命名空间。

operator:用来声明或多载一个操作符。

out:标识一个参数值会受影响的参数,但在传入方法时,该参数无需先初始化。

params:声明一个参数数组。如果使用,必须修改指定的最后一个参数,允许可选参数。

readonly:标识一个变量的值在初始化后不可修改。

ref:标识一个参数值可能会受影响的参数。

sealed:防止类型被派生,防止方法和property被覆载。

sizeof:一个操作符,以byte为单位返回一个值类型的长度。

stackalloc:返回在堆上分配的一个内存块的指针。

struct:是一种值类型,可以声明常量、字段、方法、property、索引器、操作符、构造器和内嵌类型。

throw:抛出一个异常。

try:异常处理代码块的组成部分之一。try代码块包括可能会,抛出异常的代码。参阅catch和finally关键字。

typeof:一个操作符,返回传入参数的类型。

unchecked:禁止溢出检查。unsafe:标注包含指针操作的代码块、方法或类。

using:当用于命名空间时,using关键字允许访问该命名空间中的类型,而无需指定其全名。也用于定义finalization操作的范围。

virtual:一个方法修饰符,标识可被覆载的方法。

volatile:标识一个可被操作系统、某些硬件设备或并发线程修改的attribute[8-9]

标识符

标识符是指在程序中用来表示事物的单词。

标识符命名规则:

标识符只能由数字、字母、下划线和@组成2

标识符不能以数字开头;

标识符不能是关键字,如果您想使用这些关键字作为标识符,可以在关键字前面加上 @ 字符作为前缀;

标识符区分大小写。大写字母和小写字母被认为是不同的字母;

不能与C#的类库名称相同。7

语句

语句是描述一个类型或告诉程序去执行一个动作的源代码指令,分为简单语句和块。

简单语句

简单语句以一个分号结束。

例如,下面的代码是一个由两条简单语句组成的序列。第一条语句定义了一个名称为var1的变量,并初始化它的值为5。第二条语句打印变量var1的值到屏幕窗口6

int var1 = 5;

System.Console,WriteLine("The value of var1is {0}",var1);

块是一个由成对大括号包围的0条或多条语句序列,它在语法上相当于一条语句。

可以使用之前示例中的两条语句创建一个块。用大括号把语句包围起来,如下面的代码所示6

{

int var1 = 5;

System.Console.WriteLine("Thevalue of var1 is (0}",var1);

}

注意:

可以在任何语法上只需要一条语句而你需要的行为又要求一条以上的简单语句的情况下使用块。

有些特定的程序结构只能使用块。在这些结构中,不能用简单语句替代块。

简单语句以分号结束,但块后面不跟分号。

数据类型

值类型

基本数据类型:C#拥有比C/C++或者Java更广泛的数据类型。这些类型是bool、byte、sbyte、short、ushort、int、uint、long、ulong、float、double和decimal,所有这些类型像Java一样都有一个固定的大小,像C和C++一样,每个数据类型都有有符号和无符号两种类型。与Java相同的是,一个字符变量包含的是一个16位的Unicode字符。

C#新的数据类型是decimal数据类型,其在 .NET 中被设计用来处理高精度的十进制数运算。它可以存储最多28到29位的十进制数字,具体取决于数字的值。由于其高精度特性,decimal 类型通常用于需要精确计算的金融和货币应用,以避免浮点数运算可能产生的舍入误差。对于货币数据,它能存放28位10进制数字8

Nullable类型,允许用它定义包含null值(即空值)的数据类型,定义一个nullable类型非常类似于定义一个非nullable类型。不同之处在于使用类型修饰符“?”9

比如定义一个整型如下:int myInt = 1;

要使一个整型变量可以存储一个null值,可以如下声明:

int? myNullableInt= 1;

元组 (ValueTuple)类型由一个或多个元素组成,每个元素可以是不同的数据类型。定义时需要指定其所有数据成员的类型,或者,可以指定字段名称。

引用类型

Object:所有其他类的基类,string是对象类型的派生类型,共享了Object类型提供的基础功能。

String:是一个非常核心的类,提供了丰富的方法和属性来处理文本数据。无论何时在程序中写入一句带引号的字符串,编译器会创建一个string对象来保存它8

Record:是一种用record关键字声明的新的引用类型,与类不同的是,Record有着引用类型的支持大对象、继承、多态等特性,也有着结构的基于值相等的特性。

Delegate: 在C#中,代理(Delegate)是一种特殊的类型,它持有对某个方法的引用。代理允许将方法作为参数传递给其他方法,或者将方法作为反馈(Callback)使用。这使得代理成为一种非常强大的机制,用于实现事件处理、反馈(回调)和泛型方法的多态性。

参数数组:提供了一种更加灵活和便捷的方式来处理可变数量的输入参数。定义参数数组时,数据类型前需使用 params修饰符,数据类型后放置一组空的方括号10,如:

void ListInts( params int[]inVals )

程序执行

C#所开发的程序源代码并不是编译成能够直接在操作系统上执行的二进制本地代码。与Java类似,它被编译成为中间代码,然后通过.NETFramework的虚拟机——被称之为通用语言运行库(CLR)——执行。所有的.Net编程语言都被编译成这种被称为MSIL(MicrosoftIntermediate Language )的中间代码。因此虽然最终的程序在表面上仍然与传统意义上的可执行文件都具有“.exe”的后缀名。但是实际上,如果计算机上没有安装.Net Framework,那么这些程序将不能够被执行。

在程序执行时,.Net Framework将中间代码翻译成为二进制机器码,从而使它得到正确的运行。最终的二进制代码被存储在一个缓冲区中。所以一旦程序使用了相同的代码,那么将会调用缓冲区中的版本。这样如果一个.Net程序第二次被运行,那么这种翻译不需要进行第二次,速度明显加快11

版本介绍

  • C# 1.0——纯粹的面向对象

发布时间:2002 年 1 月

C# 1.0 的主要功能:类、结构、接口、事件、属性、委托、运算符和表达式、语句、特性

  • C# 1.2

发布时间:2003 年 4 月

随 Visual Studio .NET 2003 一起提供的 C# 版本 1.2。它对语言做了一些小改进。

从此版本开始,当 IEnumerator 实现 IDisposable 时,foreach 循环中生成的代码会在 IEnumerator 上调用 Dispose。

这一时期的C#(以下称为C#1.x)提出了纯粹的面向对象概念。C++并非纯面向对象的,为了和C兼容以及提供更高的执行效率,它保留了很多模块化的东西。C#还通过类类型、值类型和接口类型的概念形成了统一的类型系统。

尽管C# 1.x提供了如此多的新鲜概念,但实际上,这些概念都是由CLI提出的。因此当将一个C#源程序编译为可执行文件时,编译器做的工作相对而言并不多。需要编译器代劳的是要将一个简单的委托定义语句翻译为一个继承System.MulticastDelegate类型定义。

  • C# 2.0——泛型编程新概念

发布时间:2005 年 11 月

C# 2.0的主要功能:泛型、分部类型、匿名方法、可以为 null 的值类型、迭代器、协变和逆变。

微软在2004年的6月份发布了Visual Studio2005的第一个Beta 版,同时向开发者展示了C#语言的2.0版本。2005年4月,微软发布了Visual Studio2005 Beta2,这已经是具备了几乎全部功能的VisualStudio,包括的产品有SQL Server2005、TeamFoundation Server和TeamSuite。这时的C#编译器已经能够处理C#2.0中所有的新特性12

C# 2.0为开发者带来的最主要的特性就是泛型编程能力。和面向对象思想一样,泛型思想也是一种已经成熟的编程思想,但依然是没有哪一种主流开发语言能够支持完备的泛型概念。这主要是因为泛型的概念在一定程度上对面向对象概念进行冲击,同时,由于在编译期间对类型参数的完全检测很难做到,很多问题会被遗留到运行时。C# 2.0别出心裁,对泛型类型参数提出了“约束”的新概念,并以优雅的语法体现在语言之中。有了约束,结合编译器强大的类型推断能力,可以在编译时发现几乎所有“危险”的泛型应用18

C# 2.0的另一个突出的特性就是匿名方法,用来取代一些短小的并且仅出现一次的委托,使得语言结构更加紧凑。匿名方法除了可以使得事件处理器的编写更加精简以外,还将开发者带入了程序设计的一个新的领域——函数式编程,曾经有高人就用匿名方法结合泛型编程实现了函数式编程中的重要结构—— Lambda 表达式。尽管这种实现显得很繁琐而且不易理解,但毕竟是实现了。

  • C#3.0——(研发代号“Orcas”)

发布时间:2007 年 11 月

C#3.0的主要功能:自动实现的属性、匿名类型、查询表达式、Lambda 表达式、表达式树、扩展方法、隐式类型本地变量、分部方法、对象和集合初始值设定项

2005年9 月份的PDC大会——C#3.0(研发代号“Orcas”——魔鬼)的技术预览版。说到C# 3.0,就不得不提一下微软的LINQ 项目,LINQ(语言集成查询,LanguageIntegrated Query)提出了一种通过面向对象语法来实现对非面向对象数据源的查询技术,可查询的数据源从关系型数据库延伸到一般意义上的集合(如数组和列表)以及XML。而C# 3.0则是率先实现了LINQ的语言。

在C# 3.0中,可以用类似于SQL语句的语法从一个数据源中轻松地得到满足一定条件的对象集合。例如要查找一个字符串数组names中所有长度大于5的字符串,就可以写:var longname = from n in nameswheren.Length > 5 select n;

这样就得到一个新的字符数组longname,其中包含了所需要的结果。这种语句称作查询语句,与SQL语句唯一的区别是C#中的查询语句往往把select子句放到最后(这反而倒有些类似于中文的阅读顺序了)。初次看到这样一个语句,可能会有很大疑问:这还是C#语言吗?这的确是合乎语法规则的C#代码,而且编译器可以识别这种语法。然而实际上,C#编译器并不会对这种语法进行实际的的编译,而是将其翻译为正常的方法调用

C# 3.0 开始为 C# 转变为面向对象/函数式混合语言奠定基础。

来源: 百度百科

内容资源由项目单位提供