成员的可访问性
CLR术语 | c#术语 | 描述 |
Private | private | 成员只能由定义类型或任何镶嵌类型中的方法访问 |
Family | protected | 成员只能由定义类型、任何镶嵌类型或不管在什么程序集中的一个派生类型中的方法访问 |
Family and Assembly | (不支持) | 成员只能由定义类型、任何镶嵌类型或同一程序集中定义的任何派生类型中的方法访问 |
Assembly | internal | 成员只能由定义程序集中的方法访问 |
Family or Assembly | protected internal | 成员可由任何嵌套类型、任何派生类型(不管什么程序集)或者定义程序集中的任何方法访问 |
Public | public | 成员可由任何程序集的任何方法访问 |
如果没有显示声明成员的可访问性,编译器通常默认选择private。CRL要求接口类型的所有成员都具有public可访问性。
一个派生类重写在他的基类型中定义的一个成员时,c#编译器要求原始成员和重写成员具有相同的可访问性。(CRL不需要)
任何成员想要被别人访问到,都必须在一个可见的类型内定义。如果程序集A定义了一个internal类型,该类型有一个public方法,那么程序集B就不能访问这个public方法。
友元程序集
友元程序集适用于定义类型是internal的类型能访问另一个定义类型也是internal的类型。
构建程序集时可以使用在system。Runtime.CompilerService命名空间中定义的一个名为InternalsVisibleTo的attribute来标明他认为是“友元”的其他程序集。这个attribute要获取一个字符串参数,这个字符串
标识了友元程序集的名称和公钥。一个程序集在确认了自己的友元程序集之后,那些友元程序集就能访问该程序集中所有internal类型,以及这些类型的internal成员。
下例展示了一个程序集如何将两个强命名程序集“Wintellect”和“Microsoft‘指定为他的友元程序集
using System
using System.Runtime.CompilerServices;//为了IntrenalVisibleTo attribute //当前程序集中的internal类型可由以下两个程序集中的任何代码访问(不管什么版本或什么语言文化) [assembly: InternalsVisibleTo("Wintellect, PublicKey=1111")] [assembly: InternalsVisibleTo("Microsoft, PublicKey=2222")] internal sealed class SomeInternalType { } internal sealed class AnotherInternalType { }
//以下为公钥为2222的友元程序集”Wintellect“如何访问上述程序集的internal类型的SomeInternalType
using System
internal sealed class Foo { private static Object SomeMethod() { //这个“Wintellect”程序集能访问另一个程序集的internal类型,就好像那是一个public一样 SomeInternalType sit = new SomeInternalType(); return sit; } }
静态类
有一些永远不需要实例化的类,例如Console,Math,Environment,ThreadPool类,这些类只有static成员。事实上这种类的唯一目作用就是将一组相关成员结合到一起,例如
Math类定义了一组执行数学运算的方法。在c#中,要用static定义不可实例化的类(static不能用于结构体)
c#对静态类做了如下限制
静态类不许直接从System Object 派生,从其他任何基类派生没有任何意义。继承只适用于对象,但是不能创建静态类的实例。
静态类不能实现任何接口,因为只有使用类的实例时,才能调用类的接口方法。
静态类只能定义静态成员,任何实例成员豆浆导致变异器报错。
静态类不能作为字段、方法参数或局部变量使用,因为他们都代表引用了一个实例的变量,而这时不允许的,编译器检测到任何这样的用法都会报错。