本页使用了标题或全文手工转换

C#

C#
C Sharp wordmark.svg
编程范型结构化面向对象泛型
语言家族C
設計者微软
實作者微软
发行时间2000年,​20年前​(2000
穩定版本
9.0[1]
(2020年11月10日,​10個月前​(2020-11-10
作業系統WindowsLinuxMac OS XAndroid
許可證
文件扩展名.cs, .csx
網站C# Language
主要實作產品
.NET Core.NET FrameworkMonoDotGNU
衍生副語言
Spec#英语Spec SharpPolyphonic C#英语Polyphonic C sharp
啟發語言
C++JavaEiffelModula-3Object Pascal
影響語言
Clojure[4] D語言F#Java 5、NemerleVala

C#微软推出的一种基于.NET框架的、面向对象的高级编程语言。C#是一种由C和C++衍生出来的面向对象的编程语言。它在继承C和C++强大功能的同时去掉了一些它们的复杂特性,使其成为C语言家族中的一种高效强大的编程语言。C#以.NET框架类库作为基础,拥有类似Visual Basic的快速开发能力。C#由安德斯·海尔斯伯格主持开发,微软在2000年发布了这种语言,希望借助这种语言来取代Java。C#已经成为Ecma国际国际标准组织的标准规范。

命名

C#的发音为“C sharp”,“#”读作“sharp”(/ʃɑːp/),命名启发于音乐上的音名“C♯”,在音乐中“C♯”表示C升半音,為比C高一点的音节,且“#”形似4个加号,微软借助这样的命名,以表示C#在一些语言特性方面对C++的提升的意思。

由於顯示器(標準字體瀏覽器等)的技術限制,且大部分的鍵盤配置上不存在升記號(♯),所以井號(#)被用於此程式語言的名稱中,約定在ECMA-334 C#語言規範中[5]

设计目标

ECMA标准列出的C#设计目标:

  • C#旨在设计成为一种「简单、现代、通用」,以及面向对象的程序设计语言
  • 此种语言的实现,应提供对于以下软件工程要素的支持:强类型檢查、数组维度检查、未初始化的变量引用检测、自动垃圾收集(Garbage Collection,指一种記憶體自動释放技术)。软件必须做到強大、持久,并具有较强的编程生产力。
  • 此种语言为在分布式环境中的开发提供适用的组件开发应用。
  • 为使程序员容易迁移到这种语言,源代码的可移植性十分重要,尤其是对于那些已熟悉C和C++的程序员而言。
  • 对国际化的支持非常重要。
  • C#适合为独立和嵌入式的系统编写程序,从使用复杂操作系统的大型系统到特定应用的小型系统均适用。
  • 虽然C#程序在存储和操作能力需求方面具备经济性,但此种语言在某些情況下并不能在性能和程式大小方面与C语言相抗衡。[來源請求]

歷史

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

版本

版本 語言規格 日期 .NET框架的版本 Visual Studio的版本
ECMA ISO/IEC Microsoft
C# 1.0 2002年12月页面存档备份,存于互联网档案馆 2003年4月页面存档备份,存于互联网档案馆 2002年1月页面存档备份,存于互联网档案馆 2002年1月 .NET Framework 1.0 Visual Studio .NET 2002
C# 1.1
C# 1.2
2003年10月页面存档备份,存于互联网档案馆 2003年4月 .NET Framework 1.1英语.NET Framework 1.1 Visual Studio .NET 2003
C# 2.0 2006年6月 2006年9月页面存档备份,存于互联网档案馆 2005年9月页面存档备份,存于互联网档案馆 2005年11月 .NET Framework 2.0 Visual Studio 2005
C# 3.0 2007年8月页面存档备份,存于互联网档案馆 2007年11月

.NET Framework 2.0 (Except LINQ)[6]
.NET Framework 3.0 (Except LINQ)[6]
.NET Framework 3.5

Visual Studio 2008
Visual Studio 2010
C# 4.0 2010年4月 2010年4月 .NET Framework 4 Visual Studio 2010
C# 5.0 2017年12月页面存档备份,存于互联网档案馆 2018年12月页面存档备份,存于互联网档案馆 2013年6月页面存档备份,存于互联网档案馆 2012年8月 .NET Framework 4.5 Visual Studio 2012
Visual Studio 2013
C# 6.0 草案页面存档备份,存于互联网档案馆 2015年7月 .NET Framework 4.6 Visual Studio 2015
C# 7.0 2017年3月 .NET Framework 4.6.2 Visual Studio 2017
C# 7.1 2017年8月 .NET Framework 4.7英语.NET Framework 4.7 Visual Studio 2017 version 15.3[7]
C# 7.2 2017年11月 .NET Framework 4.7.1 Visual Studio 2017 version 15.5[8]
C# 7.3 2018年5月 .NET Framework 4.7.2 Visual Studio 2017 version 15.7[8]
C# 8.0 2019年9月 .NET Framework 4.8 Visual Studio 2019 version 16.3[8]
C# 9.0 2020年9月 .NET 5

語言特性

相對於CC++,這個語言在許多方面進行了限制和增強:

  • 指针(Pointer)只能用於不安全模式之中。大多數對象訪問通過安全的引用实现,以避免無效的調用,並且有許多算法用於验证溢出,指针只能用於調用值类型,以及受垃圾收集控制的托管對象。
  • 對象不能被顯式釋放,代替為當不存在被引用時通過垃圾回收器回收。
  • 只允許單一繼承(single inheritance),但是一個類可以實現多個接口(interfaces)。
  • C#比C++更加類型安全。默认的安全轉換是隱含轉換,例如由短整型轉換為長整型和從派生類轉換為基類。而接口布尔型同整型,及枚举型同整型不允許隱含轉換,非空指针(通過引用相似對象)同用戶定義類型的隱含轉換字段被顯式的確定,不同於C++的複製構造函數。
  • 数组声明語法不同("int[] a = new int[5]"而不是"int a[5]")。
  • 枚举位於其所在的命名空間中。
  • C#中沒有模版(Template),但是在C# 2.0中引入了泛型(Generic programming),並且支持一些C++模版不支持的特性。比如泛型參數中的類型約束。另一方面,表達式不能像C++模版中被用於類型參數。
  • 屬性支持,使用類似訪問成員的方式調用。
  • 完整的反射支持。

C# 2.0的特性

针对于.NET SDK 2.0(相对应于ECMA-334标准第三版),C# 的新特性有:

分部類別

分部類別将類別的实现分在多个文件中。该概念于C# 中首次出现,除了能将一个類別的成员分开存放,还使ASP.NET中的代码后置得以实现。代码后置实现了HTML代码和后台交互代码的分离。

file1.cs:

public partial class MyClass1 {     public void MyMethod1()     {         // implementation     } } 

file2.cs:

public partial class MyClass1 {     public void MyMethod2()     {         // implementation     } } 

分部類別这个特性允许将一个類別的编写工作分配给多个人,一人写一个文件,便于版本控制。它又可以隔离自动生成的代码和人工书写的代码,例如设计窗体应用程序时。

泛型

泛型,或参数化类型,是被C#支持的.NET 2.0特性。不同于C++模版,.NET参数化类型是在运行时被实例化,而不是编译时,因此它可以跨语言,而C++模版却不行。它支持的一些特性并不被C++模版直接支持,比如约束泛型参数实现一个接口。另一方面,C# 不支持无类型的泛型参数。不像Java中的泛型,在CLI虚拟机中,.NET generics使用具化生成泛型参数,它允许优化和保存类型信息。[9]

静态類別

静态類別它不能被实例化,并且只能有静态成员。这同很多过程语言中的模块概念相类似。

迭代器

一种新形式的迭代器它提供了函数式编程中的generator,使用yield return

类似于Python中使用的yield

// Method that takes an iterable input (possibly an array) // and returns all even numbers. public static IEnumerable<int> GetEven(IEnumerable<int> numbers) {     foreach(int i in numbers)     {         if (i % 2 == 0) yield return i;     } } 

匿名方法

匿名方法类似于函数式编程中的闭包[10]

public void Foo(object parameter) {     // ...      ThreadPool.QueueUserWorkItem(delegate     {         // anonymous delegates have full access to local variables of the enclosing method         if(parameter == ...)         {              // ...          }          // ...     }); } 

委托的协变和逆变

委托签名的协变和逆变,[11]

属性访问器可以被单独设置访问级别

例子:

string status = string.Empty;  public string Status {     get { return status; }             // anyone can get value of this property,     protected set { status = value; }  // but only derived classes can change it } 

可空类型

可空类型(跟个问号,如int? i = null;)允许设置null给任何类类型。

int? i = null; object o = i; if(o == null)     Console.WriteLine("Correct behaviour - runtime version from September 2005 or later"); else     Console.WriteLine("Incorrect behaviour - pre-release runtime (from before September 2005)"); 

??運算子

??)用于如果類別不为空值时回傳它自身,如果为空值则返回之后的操作

object nullObj = null;  object obj = new Object();  return nullObj ?? obj; // returns obj 

主要用作将一个可空类型赋值给不可空类型的简便语法

int? i = null; int j = i ?? 0; // Unless i is null, initialize j to i. Else (if i is null), initialize j to 0. 

C# 3.0的特性

C# 3.0发布于2007年10月17日,是.NET Framework 3.5的一部分,它的新特性灵感来自于函数式编程语言,如:HaskellML,并广泛地引入了Language Integrated Query(LINQ)模式到通用語言運行庫中e.[12]

Linq

语言集成查询(英語:Language Integrated Query,缩写:LINQ):[13] 上下文相关关键字"from, where, select"可用于查询SQL、XML、集合等。这些标识符在LINQ上下文中被作为关键字,但是它们的增加不会破坏原有的名为fromwhereselect的变量。

类型初始化器

Customer c = new Customer(); c.Name = "James"; 

可写作:

Customer c = new Customer() { Name="James" }; 

集合初始化器

MyList list = new MyList(); list.Add(1); list.Add(2); 

可写作

MyList list = new MyList { 1, 2 }; 

假设MyList实现了System.Collections.IEnumerable且有一个Add方法method[14]

匿名類型

var x = new { Name="James" }; 

局部变量类型推断

局部变量类型推断

var x = new Dictionary<string, List<float>>(); 

等同于

Dictionary<string, List<float>> x = new Dictionary<string, List<float>>(); 

它只是一个语法糖,这个特性被匿名类型声明时所需要

Lambda表达式

Lambda表达式(無函式名稱的物件方法在程式語言中的表達語法):

listOfFoo.Where(     delegate(Foo x)     {         return x.Size > 10;      } ) 
可写作
listOfFoo.Where(x => x.Size > 10); 

编译器翻译Lambda表达式为强类型委托或强类型表达式树.

自动化属性

编译器将自动生成私有变量和适当的getter(get访问器)和setter(set访问器),如:

public string Name {     get;      set;  } 

扩展方法

扩展方法指,一个静态类包含this关键字作为方法的第一参数时,这个方法将被添加到该this的类型中:

public static class IntExtensions {     public static void PrintPlusOne(this int x)      {         Console.WriteLine(x + 1);     } }   int foo = 0; foo.PrintPlusOne(); 

分部方法

允许代码生成器生成方法声明作为扩展点,如果有人在另一个部分类实现了它才会被包含于原代码编译。[15]

  1. 分部方法(Partial methods)必须定义在分部类(partial classes)中
  2. 定义分部方法需要用partial做修饰符
  3. 分部方法不一定总是有执行内容的,也就是说定义的方法可以一句操作语句都没有
  4. 分部方法返回值必须是void
  5. 分部方法可以是静态(static)方法
  6. 分部方法可以包含参数,参数可以包含以下修饰词:this,ref,params
  7. 分部方法必须是私有(private)方法

例子:

partial class C {     static partial void M(int i); // defining declaration } partial class C {     static partial void M(int i)     {         dosomething();     } } 

C# 4.0的特性

動態查閱

C# 4.0新增dynamic关键字,提供動態編程(dynamic programming),把既有的靜態物件標記為動態物件,類似javascript, PythonRuby

dynamic关键字标记的字段被处理成一个特殊包装的object对象,它取消了CLI的编译时类型检查

dynamic calc = GetCalculator(); int sum = calc.Add(10, 20); 

具名參數與可選參數

public StreamReader OpenFile(     string path,     int bufferSize = 1024) { ... } 

呼叫OpenFile時,順序可以完全顛倒:

OpenFile(bufferSize: 4096, path: "foo.txt"); 

與COM组件互動

在C#中打開一個Word文件:

static void Main(string[] args) {     Word.Application wordApplication = new           Word.Application() {Visible = true};          wordApplication.Documents.Open(@"C:\plant.docx",           ReadOnly: true);   } 

在C#中指定Excel的某一格文字:

excelObj.Cells[5, 5].Value = "This is sample text"; 

泛型的协变和逆变

C# 4.0支援协变和逆变,例如在泛型介面可以加上in、out修饰字。

  public interface IComparer<in T>     {       int Compare(T left, T right);     }    public interface IEnumerable<out T> : IEnumerable   {     IEnumerator<T> GetEnumerator();   } 

C# 5.0的特性

  1. C# Evolution Matrix
  2. Async Feature (补充: async和await是一对语法糖,允许开发人员非常轻松的调用基于TASK的异步编程)async-await关键字并不会真的创建一个线程池任务,完成这个动作依赖于被调用方法中的函数。这一点在许多C#的中文教程中被忽略,导致许多学习的新手误以为await关键字会直接创建一个新的线程池任务。
  3. Caller Information

C# 6.0的特性

  1. 唯讀 Auto 屬性
  2. Auto 屬性初始設定式
  3. 具有運算式主體的函式成員:
  4. 使用靜態
  5. Null - 條件運算子
  6. 字串插值
  7. 例外狀況篩選條件
  8. nameof 運算式
  9. Catch 和 Finally 區塊中的 Await
  10. 索引初始設定式
  11. 集合初始設定式的擴充方法
  12. 改進的多載解析

C# 7.0的特性

加入 out 變數;能夠直接宣告一個變數在它要傳入的地方,當成一個 out 的引數[16]

C# 7.1的特性

  1. async``Main方法
  2. default常值運算式
  3. 推斷的 tuple 項目名稱

C# 7.2的特性

  1. 具備實值型別的參考語意
  2. 無後置具名引數
  3. 數值常值中的前置底線
  4. private protected 存取修飾詞

C# 8.0的特性

  1. 可空引用类型
  2. await yield return可异步返回的迭代器
  3. Index 索引类型和Range区间类型
  4. 允许在声明接口时为接口成员提供默认实现
  5. 递归的模式匹配
  6. 表达式形式的Switch关键字
  7. 在编译器可做类型推断的情况下,允许进一步省略类型声明

程序的执行

C#通常不被编译成为能够直接在计算机上执行的二进制本地代码。与Java类似,它被编译成为中间代码(Microsoft Intermediate Language),然后通过.NET Framework虚拟机——被称为通用语言运行库——执行。

所有的.Net编程语言都被编译成这种被称为通用中间语言的中间代码。因此虽然最终的程序在表面上仍然与传统意义上的可执行文件都具有“.exe”的后缀名。如果计算机上没有安装.Net Framework,那么这些程序会弹出对话框,要求用户下载.net framework。

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

标准化

微软公司已经向ECMA申请将C#作为一种标准。在2001年12月,ECMA发布了ECMA-334 C#语言规范。C#在2003年成为一个ISO标准(ISO/IEC 23270)。现在有一些独立的实现正在进行,包括:

C# 的Hello World程式

下面是一個在命令列上輸出Hello World的小程序,這種程序通常作為開始學習程序語言的第一個步驟:

using System;  namespace ConsoleApp1 {     class Program     {         static void Main(string[] args)         {             Console.WriteLine("Hello World!");         }     } } 

实现

C# 有5個著名的編譯器(compilers):

  1. ^ What's new in C# 9. [2020-09-04]. (原始内容存档于2020-11-29). 
  2. ^ The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.: dotnet/roslyn. November 13, 2019 –通过GitHub. 
  3. ^ CoreCLR is the runtime for .NET Core. It includes the garbage collector, JIT compiler, primitive data types and low-level classes.: dotnet/coreclr. November 13, 2019 –通过GitHub. 
  4. ^ Rich Hickey Q&A by Michael Fogus. [2017-01-11]. 
  5. ^ C# Language Specification (PDF) 4th. Ecma International. June 2006 [2012-01-26]. (原始内容 (PDF)存档于2012-12-02). 
  6. ^ 6.0 6.1 Using C# 3.0 from .NET 2.0. Danielmoth.com. 2007-05-13 [2012年10月4日]. (原始内容存档于2012-09-29). 
  7. ^ 存档副本. [2018-09-06]. (原始内容存档于2018-01-22). 
  8. ^ 8.0 8.1 8.2 存档副本. [2018-09-06]. (原始内容存档于2018-01-22). 
  9. ^ An Introduction to C# Generics. [2020-09-25]. (原始内容存档于2019-09-24). 
  10. ^ Anonymous Methods (C#). [2008-10-24]. (原始内容存档于2008-04-17). 
  11. ^ Covariance and Contravariance in Delegates (C#). [2008-10-24]. (原始内容存档于2008-10-12). 
  12. ^ Tim Anderson. C# pulling ahead of Java - Lead architect paints rosy C# picture. Reg Developer. The Register. 2006-11-14 [2007-01-20]. (原始内容存档于2007-01-21). 
  13. ^ LINQ. Microsoft MSDN. 2007 [2007-08-13]. (原始内容存档于2007-01-16) (英语). 
  14. ^ The Mellow Musings of Dr. T : What is a collection?. [2008-10-24]. (原始内容存档于2008-12-18). 
  15. ^ Partial Methods. [2007-10-06]. (原始内容存档于2007-10-16). 
  16. ^ 一覽 C# 7.0 中的新功能. [2016-09-14]. (原始内容存档于2018-10-02). 

外部連結