C# 结构和访问修饰符
声明
本文内容来自微软 MVP solenovex 的视频教程——真会C#?- 第3章 创建类型,大致和第 8 课—— struct 和 访问修饰符 对应。可在 GitHub 中查看 C# 视频教程的配套PPT
本文主要包括以下内容:
- 结构(struct)
- 访问修饰符(Access Modifiers)
结构(struct)
struct和class差不多,但是有一些不同:
- struct是值类型,class是引用类型
- struct不支持继承(除了隐式的继承了 object,具体点就是 System.ValueType)
public struct Point
{
int x, y;
public Point (int x, int y) { this.x = x; this.y = y; }
}
...
Point p1 = new Point (); // p1.x and p1.y will be 0
Point p2 = new Point (1, 1); // p1.x and p1.y will be 1
结构的成员
类能有的成员,结构也可以有,但是以下几个不行:
- 无参构造函数
- 字段初始化器
- 终结器
- virtual 或 protected 成员
结构的构建
结构有一个无参的构造函数,但是你不能对其进行重写。它会对字段进行按位归零操作。当你定义结构构造函数的时候,必须显式的为每个字段赋值。结构不可以有字段初始化器。
public struct Point
{
int x = 1; // Illegal: field initializer
int y;
public Point() {} // Illegal: parameterless constructor
public Point (int x) {this.x = x;} // Illegal: must assign field y
}
访问修饰符(Access Modifiers)
访问修饰符是关键字,用于指定成员或类型已声明的可访问性。
5 个访问修饰符
- public,完全可访问。enum 和interface 的成员默认都是这个级别
- internal,当前 assembly 或朋友 assembly 可访问,非嵌套类型的默认访问级别
- private,本类可访问。class 和 struct 的成员的默认访问级别
- protected,本类或其子类可以访问
- protected internal,联合了 protected 和 internal 的访问级别
class Class1 {} // Class1 is internal (default)
public class Class2 {}
class ClassA { int x; } // x is private (default)
class ClassB { internal int x; }
class BaseClass
{
void Foo() {} // Foo is private (default)
protected void Bar() {}
}
class Subclass : BaseClass
{
void Test1() { Foo(); } // Error - cannot access Foo
void Test2() { Bar(); } // OK
}
朋友 Assemblies
通过添加 System.Runtime.CompilerServices.InternalsVisibleTo 这个 Assembly 的属性,并指定朋友 Assembly 的名字,就可以把 internal 的成员暴露给朋友 Assembly。[assembly: InternalsVisibleTo ("Friend")]
如果朋友 Assembly 有 Strong name,那么就必须指定其完整的 160 字节的 public key。[assembly: InternalsVisibleTo ("StrongFriend, PublicKey=0024f000048c...")]
类型限制成员的访问级别
外层决定了内层最大访问级别。class C { public void Foo() {} }
访问修饰符的限制
当重写父类的函数时,重写后的函数和被重写的函数的访问级别必须一致。
class BaseClass { protected virtual void Foo() {} }
class Subclass1 : BaseClass { protected override void Foo() {} } // OK
class Subclass2 : BaseClass { public override void Foo() {} } // Error
有一个例外:当在其它 Assembly 重写 protected internal 的方法时,重写后的方法必须是 protected。
参考
Structs (C# Programming Guide)
Classes and Structs (C# Programming Guide)
struct (C# Reference)
Access Modifiers (C# Programming Guide)
Access Modifiers (C# Reference)