using System; using Acme. Collections class Example public static void Main() rar s= new Stack<int>o 5. Push(1);// stack contains 1 s Push(10);// stack contains 1, 1( ush(100);// stack contains 1, 10, 100 Console. WriteLine(s Pop();// stack contains 1, 10 Console. WriteLine (s Pop();// stack contains 1 Console. WriteLine(s Pop();// stack is empt 若要编译此程序,需要引用包含前面示例中定义的堆栈类的程序集 C#程序可以存储在多个源文件中。在编译C#程序时,捋同时处理所有源文件,并且源文件可以自由地相互引 用。从概念上讲,就好像所有源文件在被处理之前都连接到一个大文件。在C#中永远都不需要使用前向声明 因为声明顺序无关紧要(极少数例外情况除外)。C#并不限制源文件只能声明一种公共类型,也不要求源文件的 文件名必须与其中声明的类型相匹配 本教程中的后续文章介绍了这些组织块
using System; using Acme.Collections; class Example { public static void Main() { var s = new Stack<int>(); s.Push(1); // stack contains 1 s.Push(10); // stack contains 1, 10 s.Push(100); // stack contains 1, 10, 100 Console.WriteLine(s.Pop()); // stack contains 1, 10 Console.WriteLine(s.Pop()); // stack contains 1 Console.WriteLine(s.Pop()); // stack is empty } } 若要编译此程序,需要引用包含前面示例中定义的堆栈类的程序集。 C# 程序可以存储在多个源文件中。 在编译 C# 程序时,将同时处理所有源文件,并且源文件可以自由地相互引 用。 从概念上讲,就好像所有源文件在被处理之前都连接到一个大文件。 在 C# 中永远都不需要使用前向声明, 因为声明顺序无关紧要(极少数例外情况除外)。 C# 并不限制源文件只能声明一种公共类型,也不要求源文件的 文件名必须与其中声明的类型相匹配。 本教程中的后续文章介绍了这些组织块
类型和成员 2021/3/5·· Edit Online 作为面向对象的语言,C#支持封装、继承和多态性这些概念。类可能会直接继承一个父类,并且可以实现任意数 量的接口。若要用方法重写父类中的虚方法,必须使用 override关键字以免发生意外重定义。在C#中,结构 就像是轻量级类,是可以实现接口但不支持继承的堆栈分配类型。C#还可提供记录,这些记录是主要用于存储 数据值的类类型。 类和对象 类是最基本的C#类型。类是一种数据结构,可在一个单元中就捋状态(字段)和操作(方法和其他函数成员)结 合起来。类为类实例(亦称为对象")提供了定义。类支持继承和多形性,即派生类可以扩展和专门针对基类 机制。 新类使用类声明进行创建。类声明以标头开头。标头指定以下内容 ●类的特性和修饰符 类的名称 ●基类(从基类继承时) 接口由该类实现。 标头后面是类主体由在分隔符(和}内编写的成员声明列表组成 以下代码展示的是简单类 Point的声明 public class point public int xi get; I public int Yi get; public Point(int x, int y)=>(X, Y)=(x, y) 类实例是使用new运算符进行创建,此运算符为新实例分配内存,调用构造函数来初始化实例,并返回对实例 的引用。以下语句创建两个 Point对象,并将对这些对象的引用存储在两个变量中 var p1 new Point(0, 0); var p2 new Point (10, 20); 当无法再访问对象时,对象占用的内存会被自动回收。没有必要也无法在C#中显式解除分配对象。 类型参数 泛型类定义类型参数*。类型参数是用尖括号括起来的类型参数名称列表。类型参数跟在类名后面。然后,可以 在类声明的主体中使用类型参数来定义类成员。在以下示例中,Pair的类型参数是 THirst和 SEcond
类型和成员 2021/3/5 • • Edit Online 类和对象 public class Point { public int X { get; } public int Y { get; } public Point(int x, int y) => (X, Y) = (x, y); } var p1 = new Point(0, 0); var p2 = new Point(10, 20); 类型参数 作为面向对象的语言,C# 支持封装、继承和多态性这些概念。 类可能会直接继承一个父类,并且可以实现任意数 量的接口。 若要用方法重写父类中的虚方法,必须使用 override 关键字,以免发生意外重定义。 在 C# 中,结构 就像是轻量级类,是可以实现接口但不支持继承的堆栈分配类型。 C# 还可提供记录,这些记录是主要用于存储 数据值的类类型。 类 是最基本的 C# 类型。 类是一种数据结构,可在一个单元中就将状态(字段)和操作(方法和其他函数成员)结 合起来。 类为类实例(亦称为“对象”)提供了定义 。 类支持 继承 和 多形性,即 派生类 可以扩展和专门针对 基类 的机制。 新类使用类声明进行创建。 类声明以标头开头。 标头指定以下内容: 类的特性和修饰符 类的名称 基类(从基类继承时) 接口由该类实现。 标头后面是类主体,由在分隔符 { 和 } 内编写的成员声明列表组成。 以下代码展示的是简单类 Point 的声明: 类实例是使用 new 运算符进行创建,此运算符为新实例分配内存,调用构造函数来初始化实例,并返回对实例 的引用。 以下语句创建两个 Point 对象,并将对这些对象的引用存储在两个变量中: 当无法再访问对象时,对象占用的内存会被自动回收。 没有必要也无法在 C# 中显式解除分配对象。 泛型类定义类型参数*。 类型参数是用尖括号括起来的类型参数名称列表。 类型参数跟在类名后面。 然后,可以 在类声明的主体中使用类型参数来定义类成员。 在以下示例中, Pair 的类型参数是 TFirst 和 TSecond :
public class Pair<TFirst, SEcond> public TFirst First i get; 1 public SEcond Second get; public Pair(TFirst first, SEcond second)=> (First, Second)=(first, second); 声明为需要使用类型参数的类类型被称为泛型类类型"。结构、接口和委托类型也可以是泛型。使用泛型类时, 必须为每个类型参数提供类型自变量 var pair new Pair<int, string>(1,"two") int i pair First: / TFirst int string s= pair. Second; / TSecond string 包含类型自变量的泛型类型(如上面的 Paircint, string>)被称为构造泛型类型 基类 类声明可以指定基类。在类名和类型参数后面加上冒号和基类的名称。省略基类规范与从 object类型派生相 同。在以下示例中, Point3D的基类是Poit在第一个示例中, Point的基类是 object public class Point3D Point public int z i get; set; public Point3D(int x, int y, int z): base(x, y) 类继承其基类的成员。继承意味着一个类隐式包含其基类的几乎所有成员。类不继承实例、静态构造函数以及 终结器。派生类可以在其继承的成员中添加新成员但无法删除继承成员的定义。在上面的示例中,Pont3从 point继承了x和y成员,每个 Point:30实例均包含三种属性(x、和z) 可以将类类型隐式转换成其任意基类类型。类类型的变量可以引用相应类的实例或任意派生类的实例。例如 类声明如上, Point类型的变量可以引用 Point或 Point30 Point a new Point(10, 20) Point b= new Point3D(10, 20, 30) 结构 类定义可支持继承和多形性的类型。它们使你能够基于派生类的层次结构创建复杂的行为。相比之下,结构类 型是较为简单的类型,其主要目的是存储数据值*。结构不能声明基类型;它们从 System Value Type隐式派生。 不能从 struct类型派生其他 struct类型。这些类型已隐式密封 public struct Point public double yi get; 1 public Point(double x, double y)=>(X, Y)=(x, y)
public class Pair<TFirst, TSecond> { public TFirst First { get; } public TSecond Second { get; } public Pair(TFirst first, TSecond second) => (First, Second) = (first, second); } var pair = new Pair<int, string>(1, "two"); int i = pair.First; // TFirst int string s = pair.Second; // TSecond string 基类 public class Point3D : Point { public int Z { get; set; } public Point3D(int x, int y, int z) : base(x, y) { Z = z; } } Point a = new Point(10, 20); Point b = new Point3D(10, 20, 30); 结构 public struct Point { public double X { get; } public double Y { get; } public Point(double x, double y) => (X, Y) = (x, y); } 声明为需要使用类型参数的类类型被称为“泛型类类型”。 结构、接口和委托类型也可以是泛型。 使用泛型类时, 必须为每个类型参数提供类型自变量: 包含类型自变量的泛型类型(如上面的 Pair<int,string> )被称为 构造泛型类型。 类声明可以指定基类。 在类名和类型参数后面加上冒号和基类的名称。 省略基类规范与从 object 类型派生相 同。 在以下示例中, Point3D 的基类是 Point 在第一个示例中, Point 的基类是 object : 类继承其基类的成员。 继承意味着一个类隐式包含其基类的几乎所有成员。 类不继承实例、静态构造函数以及 终结器。 派生类可以在其继承的成员中添加新成员,但无法删除继承成员的定义。 在上面的示例中, Point3D 从 Point 继承了 X 和 Y 成员,每个 Point3D 实例均包含三种属性( X 、 Y 和 Z )。 可以将类类型隐式转换成其任意基类类型。 类类型的变量可以引用相应类的实例或任意派生类的实例。 例如, 类声明如上, Point 类型的变量可以引用 Point 或 Point3D : 类定义可支持继承和多形性的类型。 它们使你能够基于派生类的层次结构创建复杂的行为。 相比之下,结构类 型是较为简单的类型,其主要目的是存储数据值*。 结构不能声明基类型;它们从 System.ValueType 隐式派生。 不能从 struct 类型派生其他 struct 类型。 这些类型已隐式密封
接口 接口定义了可由类和结构实现的协定。接口可以包含方法、属性、事件和索引器。接口通常不提供所定义成员的 实现,仅指定必须由实现接口的类或结构提供的成员 接口可以采用多重维承。在以下示例中接口obso同时继承自reox和 IListBox interface IControl void Paint( interface ITextBox IControl void SetText(string text): interface iListBox IControl void SetItems(string[] items); interface IComboBox ITextBox, IListBox i 3 类和结构可以实现多个接口。在以下示例中,类 EditBox同时实现 IControl和 IDataBoun interface IDataBound void Bind (Binder b) public class EditBox IControl, IDataBound public void Paint(i) public void Bind(Binder b)i y 当类或结构实现特定接口时,此类或结构的实例可以隐式转换成相应的接口类型。例如 EditBox editBox new EditBox(; IControl control editBox IDataBound dataBound editBox; 枚举 枚举类型定义了一组常数值。以下emum声明了定义不同根蔬菜的常数: public enum Some Rootvegetable Radish Turnip 还可以定义一个emum作为标志组合使用。以下声明为四季声明了一组标志。可以随意搭配季节组合,包括 A1值(包含所有季节)
接口 interface IControl { void Paint(); } interface ITextBox : IControl { void SetText(string text); } interface IListBox : IControl { void SetItems(string[] items); } interface IComboBox : ITextBox, IListBox { } interface IDataBound { void Bind(Binder b); } public class EditBox : IControl, IDataBound { public void Paint() { } public void Bind(Binder b) { } } EditBox editBox = new EditBox(); IControl control = editBox; IDataBound dataBound = editBox; 枚举 public enum SomeRootVegetable { HorseRadish, Radish, Turnip } 接口定义了可由类和结构实现的协定。 接口可以包含方法、属性、事件和索引器。 接口通常不提供所定义成员的 实现,仅指定必须由实现接口的类或结构提供的成员。 接口可以采用“多重继承”。 在以下示例中,接口 IComboBox 同时继承自 ITextBox 和 IListBox 。 类和结构可以实现多个接口。 在以下示例中,类 EditBox 同时实现 IControl 和 IDataBound 。 当类或结构实现特定接口时,此类或结构的实例可以隐式转换成相应的接口类型。 例如 枚举类型定义了一组常数值。 以下 enum 声明了定义不同根蔬菜的常数: 还可以定义一个 enum 作为标志组合使用。 以下声明为四季声明了一组标志。 可以随意搭配季节组合,包括 All 值(包含所有季节):
[ Flags] public enum Seasons Summer 1 Autumn 2 pring =8 All Summer I Autumn I winter I Spring 以下示例显示了前面两个枚举的声明 ar turnip SomeRootvegetable Turnip var spring Seasons Spring; var startingOnEquinox Seasons Spring I Seasons. Autumn var the Year Seasons All; 可为nu的类型 任何类型的变量都可以声明为不可为mu或可为nu"。可为nu的变量包含一个额外的nll值,表示没有 值。可为nu的值类型(结构或枚举)由 System Nullable<T>表示。不可为nu和可为nu的引用类型都由基 础引用类型表示。这种区别由编译器和某些库读取的元数据体现。当可为nu的引用在没有先对照nu检查 其值的情况下取消引用时,编译器会发出警告。当对不可为nu的引用分配了可能为mul的值时,编译器也会 发出警告。以下示例声明了可为nu的int,并将其初始化为nu。然后捋值设置为5。该例通过“可为nul 的字符串"演示了同一概念。有关详细信息,请参阅可为nul的值类型和可为nu的引用类型 int? optionalInt default optionalInt = 5: string? optionalText default; optionalText ="Hello World 元组 C#支持元组,后者提供了简洁的语法来将多个数据元素分组成一个轻型数据结构。通过声明(和)之间的 成员的类型和名称来实例化元组,如下例所示 (double int Count) t2=(4.5 Console. WriteLine($"Sum of (t2. Count) elements is it2. Sum). " / Sum of 3 elements is 4.5 元组为具有多个成员的数据结构提供了一种替代方法,且无需使用下一篇文章中介绍的构建基块
[Flags] public enum Seasons { None = 0, Summer = 1, Autumn = 2, Winter = 4, Spring = 8, All = Summer | Autumn | Winter | Spring } var turnip = SomeRootVegetable.Turnip; var spring = Seasons.Spring; var startingOnEquinox = Seasons.Spring | Seasons.Autumn; var theYear = Seasons.All; 可为 null 的类型 int? optionalInt = default; optionalInt = 5; string? optionalText = default; optionalText = "Hello World."; 元组 (double Sum, int Count) t2 = (4.5, 3); Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}."); // Output: // Sum of 3 elements is 4.5. 以下示例显示了前面两个枚举的声明: 任何类型的变量都可以声明为“不可为 null”或“可为 null” 。 可为 null 的变量包含一个额外的 null 值,表示没有 值。 可为 null 的值类型(结构或枚举)由 System.Nullable<T> 表示。 不可为 null 和可为 null 的引用类型都由基 础引用类型表示。 这种区别由编译器和某些库读取的元数据体现。 当可为 null 的引用在没有先对照 null 检查 其值的情况下取消引用时,编译器会发出警告。 当对不可为 null 的引用分配了可能为 null 的值时,编译器也会 发出警告。 以下示例声明了“可为 null 的 int”,并将其初始化为 null 。 然后将值设置为 5 。 该例通过“可为 null 的字符串”演示了同一概念。 有关详细信息,请参阅可为 null 的值类型和可为 null 的引用类型。 C# 支持元组,后者提供了简洁的语法来将多个数据元素分组成一个轻型数据结构*。 通过声明 ( 和 ) 之间的 成员的类型和名称来实例化元组,如下例所示: 元组为具有多个成员的数据结构提供了一种替代方法,且无需使用下一篇文章中介绍的构建基块