[一起来阅读《C#图解教程》吧] -- 类

成员修饰符的顺序

  • 按照**【特性】【修饰符】核心声明 **的书序来排列
  • 如果有多个修饰符,则修饰符之间的顺序是任意的,如以下这两个是一致的:
    • public static int a ;
    • static public int a;
  • image.png

静态字段

  • 静态字段被类的所有实例共享,所有实例都访问同一内存位置。因此,如果该内存位置的值被一个实例改变了,这种改变对所有的实例都可见。
  • 如果从外部访问,可以使用 类名.变量名来进行访问。
  • 即使类没有实例,也存在静态成员,并且可以访问,并且我们可以对类的静态成员进行赋值。

image.png

静态函数

  • 如同静态字段,静态函数成员独立于任何类实例。即使没有类的实例,仍然可以调用静态方法。
  • 静态函数成员不能访问实例成员。然而,它们能访问其他静态成员。

注意

  • 字段、类型、方法、属性、构造函数、运算符、事件可以声明为static;
  • 常量、索引器不能声明为static

成员常量

  • 成员常量类似前一章所述的本地常量,只是它们被声明在类声明中而不是方法内。
  • 本地常量类似,用于初始化成员常量的值在编译时必须是可计算的,而且通常是一个预定义简单类型或由它们组成的表达式。
  • 与本地常量类似,不能在成员常量声明以后给它赋值。
  • 成员常量比本地常量更有趣,因为它们表现得像静态值。它们对类的每个实例都是“可见的",而且即使没有类的实例也可以使用。与真正的静态量不同,常量没有自己的存储位置,而是在编译时被编译器替换这种方式类似于c和c++中的#define值。
  • 虽然常量成员表现得像一个静态量,但不能将常量声明为static
  • image.png

属性

  • 与字段不同,属性是一个函数成员。
  • 它不为数据存储分配内存。
  • 它执行代码,是指定的一组两个匹配的、称为访问器的方法。
  • Set访问器拥有一个单独的、隐式的值参,名称为value,与属性的类型相同;一个返回类型void。
  • Get访问器拥有一个与属性类型相同的返回类型,它没有参数。

常规用法

  • 写入和读取属性的方法与访问字段一样。访问器被隐式调用。
  • 属性会根据是写入还是读取,来隐式地调用适当的访问器。不能显式地调用访问器,这样做会产生编译错误

image.png

  • 一种常见的方式是在类中将字段声明为 private以封装该字段,并声明一个public属性来控制从类的外部对该字段的访问。和属性关联的字段常被称为后备字段或后备存储

只读和只写

  • 只有get访问器的属性称为只读属性。只读属性是一种安全的,把一项数据从类或类的实例中传出,而不允许太多访问方法。
  • 只有set访问器的属性称为只写属性。只写属性是一种安全的,把一项数据从类的外部传人类,而不允许太多访问的方法。
  • 两个访问器中至少有一个必须定义,否则编译器会产生一条错误信息。

属性与公共字段

  • 属性是函数型成员而不是数据成员,允许你处理输入和输出,而公共字段不行。
  • 属性可以只读或只写,而字段不行。
  • 编译后的变量和编译后的属性语义不同。

自动实现属性

c#提供了自动实现属性(automatically皿plementedpr e可或auto-implemented property),允许只声明属性而不声明后备字段。编译器会为你创建隐藏的后备字段:并且自动挂接到get和set访问器上。

静态属性

  • 属性也可以声明为static静态属性的访问器和所有静态成员一样。
  • 不能访问类的实例成员一一一虽然它们能被实例成员访问口不管类是否有实例,它们都是存在的
  • 当从类的外部访问时,必需使用类名引用,而不是实例名。

实例构造函数

  • 如果在类的声明中没有显式地提供实例构造函数,那么编译器会提供一个隐式的默认构造函数,它没有参数,方法体为空。
  • 如果你为类声明了任何构造函数,那么编译器将不会为该类定义默认的构造函数。

静态构造函数

构造函数也可以声明为static。实例构造函数初始化类的每个新实例,而static构造函数初始化类级别的项。通常,静态构造函数初始化类的静态字段。

  • 初始化类级别的项。
    • 在引用任何静态成员之前。
    • 在创建类的任何实例之前。
  • 如同静态方法,静态构造函数不能访问所在类的实例成员,因此也不能使用this访问器
  • 不能从程序中显式调用静态构造函数,系统会自动调用它们,在:类的任何实例被创建之前;类的任何静态成员被引用之前
class RandonNumberC1ass{
  private static Random RandomKey;
  
  static RandomNumberClass(){
    RondomKey = new Random();
  }
}

静态构造函数与实例构造函数异同

  • 同:静态构造函数的名称必须和类名相同,静态构造函数不能返回值。
  • 异:
    • 静态构造函数声明中使用static关键字。
    • 类只能有一个静态构造函数,而且不能带参数。
    • 静态构造函数不能有访问修饰符。

对象初始化语句

  • 创建对象的代码必须能够访问孌初始化的字段和属性。
  • 初始化发生在构造方法执行之后,因此在构造方法中设置的值可能会在之后对象初始化中重置为相同或不同的值。

readonly 修饰符

  • 字段可以用readonly修饰符声明。其作用类似于将字段声明为const,一但值被设定就不能改。const字段只能在字段的声明语句中初始化,而readonly字段可以在下列任意位置设置它的值。
    • readonly 可出现在字段声明语句,类似const。
    • readonly 可出现在类的任何构造函数。如果是static字段,初始化必须在静态构造函数中完成。
  • const字段的值必须在编译时决定,而readonly字段的值可以在运行时决定这种增加的自由性允许你在不同的环境或不同的构造函数中设置不同的值。
  • 和const不同,const的行为总是静态的,而对于readonly字段以下两点是正确的
    • 它可以是实例字段,也可以是静态字段。
    • 它在内存中有存储位置。

示例

image.png
如上,readonly可以在声明字段的时候进行修饰,而它的初始化可以在任意位置,这一点与const不同。


索引器

索引器是一组get和set访问器,与属性类似。下图展示了一个类的索引器的表现形式,该类可以获取和设置string类型值
image.png

  • 和属性一样,索引器不用分配内存来存储
  • 索引器和属性都主要被用来访问其他数据成员,它们与这些成员关联,并为它们提供获取和设置访问。属性通常表示单独的数据成员,索引器通常表示多个数据成员

image.png

    class MyClass
    {
        private int a;
        private int b;

        public int this[int index]
        {
            get
            {
                return (0 == index) ? a : b;
            }
            set
            {
                if (Equals(0 == index))
                {
                    a = value;
                }
                else
                {
                    b = value;
                }
            }
        }
    }
    
    //调用
    MyClass c = new MyClass();
    c[0] = 2;
    c[1] = 1;

索引器重载

只要索引器的参数列表不同,类就可以有任意多个索引器。索引器类型不同是不够的这叫做索引器重载。如下:
image.png

访问器的限制

  • 仅当成员(属性或索引器)既有get访问器也有set访问器时,其访问器才能有访问修饰符
  • 虽然两个访问器都必须出现,但它们中只能有一个有访问修饰符。
  • 访问器的访问修饰符必须比成员的访问级别有更严格的限制性。

分部类和分部类型

类的声明可以分割成几个分部类的声明,类的分部类声明可以在同一文件中也可以在不同文件中,每个局部声明必须被标为partial class。分部类声明看起来和普通类声明相同,除了那个附加的类型修饰符partial

分部方法

分部方法是声明在分部类中不同部分的方法。分部方法的不同部分可以声明在不同的分部类中,也可以声明在同一个类中。分部方法的两个部分如下

  • 定义分部方法声明
    • 给出签名和返回类型。
    • 声明的实现部分只是一个分号
  • 实现分部方法声明
    • 给出签名和返回类型
    • 是以正常形式的语句块实现。
  • 定义声明和实现声明的签名和返回类型必须匹配。签名和返回类型有如下特征
    • 返回类型必须是void
    • 签名不能包括访问修饰符,这使分部方法是隐式私有的
    • 参数列表不能包含。out参数
    • 在定义声明和实现声明中都必须包含上下文关键字partial,直接放在关键字void之前
  • 可以有定义部分而没有实现部分。在这种情况下,编译器把方法的声明以及方法内部任何对方法的调用都移除。不能只有分部方法的实现部分而没有定义部分

image.png

posted @   LemonInCup  阅读(177)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示