第6章 类型和成员基础

在本章及本部分后续的章节,我将解释如何在一个类型中定义不同种类的成员,从而设计出符合自己需要的类型。

6.1类型的各种成员

在一个类型中可以定义0个或多个以下种类的成员:

  • 常量:常量就是指出数据值恒定不变的一个符号。这些符号通常用于使代码更容易阅读和维护。常量通常与类型关联,不与类型的实例关联。从逻辑上讲,常量始终是静态成员。
  • 字段:字段表示一个只读或可读可写的数据值。字段可以是静态的,这种情况下,字段被认为是类型状态的一部分。字段也可以是实例(非静态),这种情况下,字段被认为是对象状态的一部分。强烈建议将字段声明为私有的,防止类型或对象的状态被该类型外部的代码破坏。
  • 实例构造器:将对象的实例字段初始化为良好初始状态的一种特殊方法。
  • 类型构造器:将类型的静态字段初始化为良好初始状态的一种特殊方法。
  • 方法:方法是一种特殊的函数,作用是更改或查询一个类型或对象的状态。作用于类型时,称为静态方法;作用于对象时,称为实例方法。方法一般会对类型或对象的字段执行读写操作。
  • 操作符重载: 操作符重载实际是一种方法,它定义了将一个特定的操作符作用于对象时,应该如何操作这个对象。
  • 转换符重载:转换操作符是定义如何隐式或显示的将对象从一种类型转型为另一种类型的方法。
  • 属性:领用属性(property),可以使用一种简单的、字段风格的语法来设置或查询类型或对象的部分逻辑状态,同时保证状态不被遭到破坏。作用于类型的称为静态属性,作用于对象的称为实例属性。属性可以是没有参数的,也可以是有多个参数的。
  • 事件:利用静态事件,一个类型可以向一个或多个静态或实例方法发送通知。而利用实例事件,一个对象可以向一个或多个静态或实例方法发送通知。提供事件的类型或对象的状态发生改变,通常就会引发事件。事件包含两种方法,允许静态或实例方法登记或注销对该事件的关注。
  • 类型:类型可定义嵌套于其中的其他类型。通常用这个办法将一个大的、复杂的类型分解成更小的构建单元(building block),以简化实现。

无论使用什么编程语言,它的编译器都必须能处理你的源代码,为上述列表中的每一种成员生成元数据和IL代码。无论使用的编程语言是什么,元数据的格式都是完全一致的。正是因为这个特点,才使CLR成为公共语言运行时。

CLR使用公共元数据格式决定常量、字段、构造器、方法、属性和事件在运行时的行为。元数据是整个.Net Framework开发平台的关键,它实现了编程语言、类型和对象的无缝集成。

以下C#代码展示了一个类型定义,其中包含了所有可能的成员。

6.2类型的可见性

在文件范围内定义类型时,可以将类型的可见性指定为public和internal。

public类型不仅对它的定义程序集中的所有代码可见,还对其他程序集中的代码可见。

internal类型仅对定义程序集中的所有代码可见,对其他程序集中的代码不可见。

定义类型时,如果不显式指定类型的可见性,C#编译器默认将类型的可见性设为internal(两者中较有限的那一个)。

友元程序集

友元程序集功能用于访问内部成员;私有类型和私有成员仍然不可访问。

若要使程序集(程序集 B)能够访问另一个程序集(程序集 A)的内部类型和成员,应使用程序集 A 中的 InternalsVisibleToAttribute 属性

6.3成员的可访问性accessibility

在代码中引用一个成员时,成员的可访问性指出这种引用是否合法。

  • private:访问仅限于包含该成员的类型或任何嵌套类型中的方法访问。
  • protected:访问仅限于当前类和其子类。
  • internal:访问仅限于所属程序集。
  • internal protected:访问仅限于当前程序集或其子类(子类可以不属于当前程序集)。
  • public:访问不受限制。

当然,任何成员想要被别人访问到,都必须在一个可见的类型内定义。例如,如果程序集AssemblyA定义了一个internal类型,该类型有一个public方法,那么程序集AssemblyB中的代码不能调用AssemblyA中的public方法,因为internal类型对于AssemblyB是不可见的。

在C#中,如果没有显式声明成员的可访问性,编译器通常默认选择private(限制最大的那个)。CLR要求接口类型的所有成员都具有public可访问性。

6.4静态类

静态类是不能实例化的,例如Console,Math,Environment和ThreadPool类。这些类只有static成员。我们直接使用它的属性与方法,静态类最大的特点就是共享,作用是将一组相关的成员组合到一起。例如Math类中定义了一组执行数学运算的方法。Math 类:为三角函数、对数函数和其他通用数学函数提供常数和静态方法。

static关键字只能应用于类,不能应用于结构(值类型)。这是因为CLR总是允许值类型实例化。

静态类的主要特点如下:

  • 它们仅包含静态成员。
  • 它们不能被实例化。
  • 它们是密封的。
  • 它们不能包含实例构造函数。

C#编译器对静态类进行了如下限制:

  • 静态类必须直接从基类System.Object派生,从其他任何基类派生没有任何意义。继承只适用于对象,而你不能创建静态类的实例
  • 静态类不能实现任何接口,这是因为只有使用类的一个实例时,才可以调用类的接口方法
  • 静态类只能定义静态成员(字段、方法、属性和事件),任何实例成员都将导致编译器报错
  • 静态类不能作为字段、方法参数或局部变量使用,因为它们都代表引用了一个实例的变量,这是不允许的

在类或结构内部定义的类型称为嵌套类型。例如:

class Container

{

    class Nested

    {

        Nested() { }

    }

}

通过static关键字修饰,是属于类,实例成员属于对象,在这个类第一次加载的时候,这个类下面的所有静态成员会被加载。

实例构造函数:使用 new 表达式创建某个类的对象时,会使用实例构造函数创建和初始化所有实例成员变量。

只要创建基于 CoOrds 类的对象,就会调用此实例构造函数。 诸如此类不带参数的构造函数称为“默认构造函数”。 然而,提供其他构造函数通常十分有用。 例如,可以向 CoOrds 类添加构造函数,以便可以为数据成员指定初始值:

class CoOrds

{

    public int x, y;

    // constructor

    public CoOrds()

    {

        x = 0;

        y = 0;

    }

    public CoOrds(int x, int y)

    {

        this.x = x;

        this.y = y;

    }

}

class MainClass

{

    static void Main()

    {

        CoOrds p1 = new CoOrds();

        CoOrds p2 = new CoOrds(5, 3);

    }

}

6.5 分部类、结构和接口

partial这个关键字告诉C#编译器,一个类、结构或者接口的定义源代码可能要分散到一个或多个源代码文件中。

当使用大项目或自动生成的代码(如由 Windows 窗体设计器提供的代码)时,将一个类、结构或接口类型拆分到多个文件中的做法就很有用。

局部类型适用于以下情况:

  • 类型特别大,不宜放在一个文件中实现。
  • 一个类型中的一部分代码为自动化工具生成的代码,不宜与我们自己编写的代码混合在一起。
  • 需要多人合作编写一个类。

局部类型的注意点:

  • 关键字partial是一个上下文关键字,只有和 class、struct、interface 放在一起时才有关键字的含义。因此partial的引入不会影响现有代码中名称为partial的变量。
  • 局部类型的各个部分一般是分开放在几个不同的.cs文件中,但C#编译器允许我们将他们放在同一文件中。

6.6组件、多态和版本控制

组件软件编程(Component Software Programming)

下面列举了组件的一些特点:

  • 组件(.Net中称为程序集)有已经发布的意思
  • 组件有自己的标识(名称、版本、语言文化和公钥)
  • 组件永远维持自己的标识(程序集中代码永远不会静态链接到另一个程序集中,.Net总是使用动态链接)
  • 组件清楚指明它所依赖的组件(引用元数据表)
  • 组件要文档化它的类和成员,C#语言通过源代码的XML文档和编译器的/doc命名行开关提供这个功能
  • 组件必须指定它要求的安全权限,CLR的代码访问安全性(Code Access Security)机制提供了这个功能
  • 组件要发布一个在任何“维护版本”中都不会改变的接口

在.Net中,版本号为1.2.3.4的程序集,其主版本号1,次版本号2,内部版本号3,修订号为4。

6.6.1 CLR如何调用虚方法、属性和事件

方法代表在类型或者类型的实例执行某些操作的代码。

在类型上执行操作称为静态方法。在类型的实例上执行操作称为非静态方法。

任何方法都有一个名称、一个签名和一个返回值(可以是void)。

时间: 2024-10-20 21:22:29

第6章 类型和成员基础的相关文章

CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段

编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32();  // a = 0 a = 1; 等价于: int a = 1; 这种语法不仅增强了代码的可读性,其生成的IL代码与使用System.Int32时生成的IL代码是完全一致的. 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到Framework类库(FCL)中存在的类型.如C#中,int直接映射

06.类型和成员基础

在一个类型中,可以定义0个或多个以下种类的成员 常量 字段 实例构造器:将新对象的实例字段初始化为良好初始状态的一种特殊方法 类型构造器:将类型的静态字段初始为良好初始状态的一种特殊方法 方法 操作符重载 转换操作符 属性 事件 类型:类型可定义嵌套于其中的其他类型,通常用这个办法将一个大的.复杂的类型分解成更小的构建单元,以简化实现 友元程序集 假定有三个开发人员A,B,C,A希望开发的程序集给B开发的程序集访问,但不想C开发的程序集访问,则A在开发程序集的时候,可以将B开发的程序集设置为友元

(6)类型和成员基础

6.1 类型的各种成员 在一个类型中,可以定义0个或者多个以下种类的成员: 常量 常量是在编译时设置其值并且永远不能更改其值的字段.使用常量可以为特殊值提供有意义的名称以代替数字文本,以使代码变得更容易阅读及维护.定义常量请使用关键字const.private const Int32 SomeConstant = 1; 字段 字段存储着类满足其设计所必须拥有的数据.例如,表示日历日期的类可能有三个整数字段:一个表示月份,一个表示日期,还有一个表示年份.强烈建议将字段声明为私有字段,防止类型的状态

【C#进阶系列】06 类型和成员基础

这些东西是基础中的基础,基本上是本书都会讲这个.但是很多东西到处都有,所以只捡了以下的这些写下来. 关于类型的可见性和可访问性 也就是public,internal这种东西,但是还是有个东西要提一下,那就是友元程序集. 利用System.Runtime.CompilerServices中的InternalsVisibleTo这个特性,使得从友元程序集访问指定程序集的internal类型.(它的作用是通过给定公钥和友元程序集名称来访问internal方法与属性,其实就是为了让别的公司的人访问不了,

类型和成员基础

一.类型的各种成员 在一个class中,可以包含8类成员: 1.常量 2.字段 3.实例构造器 4.类型构造器 5.方法(包括操作符重载,转换操作符) 6.属性 7.事件 8.类型 二.类型的可见性 1.C#编译器默认将类型的可见性设置为internal 2.类型的可见性有public和internal两类. 三.成员的可访问性 1.C#编译器默认将成员的可访问性设置为private 2.成员的可访问性有5类:private,protected,internal,protected intern

JavaSE8基础 在构造代码块中给final类型的成员变量赋值

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        代码: /* * final 修饰值类型的成员变量. */ class Demo { final int num; { num = 1;//在构造代码块中给final类型变量赋值 //num = 2; 但是 不能重复赋值.比如,在num=1后面加上num=2,就会报错! } public static void ma

C#反射与特性(三):反射类型的成员

目录 1,获取类型的信息 1.1 类型的基类和接口 1.2 获取属性.字段成员 上一篇文章中,介绍如何获取 Type 类型,Type 类型是反射的基础. 本篇文章中,将使用 Type 去获取成员信息,通过打印出反射获取到的信息,为后续操作反射打好基础. 1,获取类型的信息 我们常常可以看到 函数.方法这两个词,很多人对此进行了混用. 方法,就是 public void Test(){} 这样的形式: 函数,指具有确定命名的.并且可以通过名称调用的代码,属性.字段.方法.委托.事件等: 只要能够通

【STM32H7教程】第39章 STM32H7的DMAMUX基础知识(重要)

完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第39章       STM32H7的DMAMUX基础知识(重要) 本章教程为大家讲解DMAMUX(Direct memory access request multiplexer,直接存储器访问请求复用器),本章知识点非常重要,是掌握好DMA1,DMA2和BDMA的关键一步. 39.1 初学者重要提示 39.2 DMAMUX基础知识 39.3 DMAMUX的HAL库

《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型 (转)

第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以跳过本章. 本章将带你漫游使用实体框架建模的基本实例,建模是实体框架的核心特性,同时也是区别实体框架和微软早期的数据访问平台的特性.一旦建好模,你就可以面向模型编写代码,而不用面向关系数据库中的行和列. 本章以创建一个简单概念模型的实例开始,然后让实体框架创建底层的数据库,剩下的实例,将向你展示,如