前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C Sharp(三)

C Sharp(三)

作者头像
1ess
修改2021-11-01 15:54:24
5920
修改2021-11-01 15:54:24
举报

C Sharp(三)

發佈於 2018-10-19

这一篇,我们深入理解一下 C# 中的类。

类的成员


上篇我们说过了 2 个类成员: 字段和方法。这一篇我们介绍除了事件和运算符之外的成员。

成员修饰符的顺序

成员声明语句有下列部分组成: 核心声明,可选的修饰符和可选的特性(attribute)。 [特性] [修饰符] 核心声明; 我们之前说过的 public 和 private 都是修饰符,还有 static 和 const 也都是修饰符。

实例成员

成员可以关联到一个类的实例,也可以关联到类的整体,默认情况下,成员被关联到一个实例,这些成员称为实例成员。

class MyClass { public int a; } class Program { static void Main() { var cls1 = new MyClass(); var cls2 = new MyClass(); cls1.a = 10; cls2.a = 20; Console.WriteLine("{0} -- {1}", cls1.a, cls2.a); // 10 -- 20 } }

静态成员

除了实例成员,类还可以拥有静态成员。静态成员被所有实例共享,访问内存同一位置,使用 static 修饰符将成员声明为静态。

class MyClass { int Mem1; static int Mem2; } class Program { static void Main() { var cls1 = new MyClass(); var cls2 = new MyClass(); cls1.Mem1 = 10; MyClass.Mem2 = 1; cls2.Mem1 = 20; MyClass.Mem2 = 2; Console.WriteLine("{0} -- {1}", cls1.Mem1 , cls2.Mem1 ); // 10 -- 20 Console.WriteLine(MyClass.Mem2); // 2 } }

类外访问静态成员

与实例成员一样在类外使用点运算符来访问静态成员,只不过是使用类名来访问。 静态函数成员不能访问实例成员,他们可以访问其他静态成员。

class X { public static int A; public static void PrintA() { Console.WriteLine(A); //可以在静态方法访问静态字段 } }

除了常量索引器,其他成员都可以是静态成员。

成员常量

如同本地常量一样,只是成员常量被声明在类中:

class MyClass { const int IntVal = 5; }

成员常量表现得很像静态值,他们对每个实例都是可见的,但是他们没有自己的存储位置,只是在编译期被替换。类似于 C 语言的 #define。

class MyClass { public const double PI = 3.14156; } class Program { static void Main() { Console.WriteLine(MyClass.PI); // 3.14156 } }

注意: 虽然成员常量表现得像静态量,但是不能使用 static 修饰符修饰。

属性

C# 中的属性非常像 Swift 中的计算属性。他们在使用时非常像字段,但是和字段不同的是,他们是函数成员,可以执行代码。

int MyVal { get { //get } set { //set } }

set 访问器拥有一个隐式的名为 value 的值参数,与属性类型相同,返回值为 void。 get 访问器没有参数,有一个与属性相同类型的返回值。 我们要注意: 属性本身没有任何存储,通常要有一个关联字段作为存储。

private int _intVal; public int IntVal { set { _intVal = value; } get { return _intVal; } }

我们还可以设置只读属性(只有 get 方法)或者只写属性(只有 set 方法),但是两个访问器至少要定义一个,否则编译器会报错。 C# 还提供了自动属性实现,不需要提供关联字段,也不需要提供访问器的方法体,get 和 set 后直接跟分号。

class MyClass { public int IntVal {get; set;} }

属性也可以被声明为静态,与静态字段一样,使用类名访问静态属性。

实例构造函数

构造函数是一个特殊的方法,他在创建类实例时执行,用于初始化实例状态。通常声明为 public。 它的特点是:

  • 构造函数没有返回值
  • 构造函数名称与类名相同

class MyClass { public MyClass() { //... } }

构造函数也可以被重载,带有不同的参数:

class Class1 { int Id; string Name; public Class1() { Id = 1; Name="1ess"; } public Class1(int Id) { this.Id = Id; Name="1ess"; } public Class1(string Name) { Id = 1; this.Name=Name; } }

如果我们没有为类提供构造函数,那么编译器会隐式提供一个无参构造函数,方法体为空。 如果我们显示提供了一个构造函数,那么就不会为我们创建一个隐式的无参构造函数。

class Class2 { int Id; string Name; public Class2(int Id) { this.Id = Id; Name="1ess"; } public Class2(string Name) { Id = 1; this.Name=Name; } } class Program { static void Main() { Class2 cls2 = new Class2(); // 错误,编译器不会再隐式提供无参构造函数 } }

静态构造函数

这一点与很多语言不同,构造函数也可以是静态的,用来初始化静态成员。调用时机是:

  • 在引用任何静态成员之前
  • 在创建类的任何实例之前

静态构造函数的特点是:

  • 名称必须与类名相同
  • 不能有返回值
  • 只能有一个静态构造函数
  • 不能有参数
  • 不能有访问修饰符

class Class1 { static Class1() { //执行静态成员初始化 } }

在静态构造函数不能访问实例成员,我们也不能显示的调用静态构造函数。

对象初始化语句

对象初始化语句扩展创建语法,在表达式的尾部放置一组成员初始化语句,允许我们在创建实例时,设置字段和属性值。 该语法有两种形式:

  • 包括构造函数的参数列表
  • 不包括构造函数的参数列表

new TypeName(ArgList) { FieldOrProp = InitVal, FieldOrProp = InitVal, ...}; new TypeName { FieldOrProp = InitVal, FieldOrProp = InitVal, ...};

要注意: 初始化列表中的字段和属性都是可访问的(public),并且初始化语句执行于构造方法之后

this 关键字

this 是对当前实例的引用,只能被用于:

  • 实例构造方法
  • 实例方法
  • 属性和索引器的实例访问器

this 的目的用于区分成员和本地变量:

class Class1 { int a; public void Say(int a) { this.a = a; //.... } }

不推荐参数和字段同名。

分部类和分部类型

类的声明可以分割成几个分部类声明:

  • 每个分部类都含有一些类成员声明
  • 每个局部声明必须标记为 partial class

partial class MyClass { int a; } partial class MyClass { int b; }

除了分部类,还有分部结构和分部接口,我们之后说。

分部方法

分部方法是声明在分部类的不同部分的方法。 分部方法两部分如下:

  • 分部方法的声明
  • 分部方法的实现

分部方法的特征:

  • 声明部分和实现部分的返回值和方法签名必须一致,并且,返回值必须是 void
  • 不能有访问修饰符修饰,也就是分部方法隐式私有
  • 不能有输出参数
  • 方法声明和方法实现之前要有 partial 修饰

partial class MyClass1 { partial void Add(int a, int b); public void PrintSum(int a, int b) { Add(a, b); } } partial class MyClass1 { partial void Add(int a, int b) { Console.WriteLine($"a + b = {a + b}"); } } class Program { static void Main() { var cls = new MyClass1(); cls.PrintSum(5, 6); // 11 } }

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 类的成员
    • 成员修饰符的顺序
      • 实例成员
        • 静态成员
          • 类外访问静态成员
            • 成员常量
              • 属性
                • 实例构造函数
                  • 静态构造函数
                    • 对象初始化语句
                      • this 关键字
                        • 分部类和分部类型
                          • 分部方法
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档