-
在面向对象编程中,封装的作用不仅仅是组合数据和行为,还能隐藏类中的数据和行为的实现细节,使类的内部工作机制不暴露。这减少了调用者对数据进行不恰当修改的几率,同时防止类的使用者根据类的内部实现来编程
-
只读属性意思是说属性中只有get,没有set ,或者set是private的
-
C#允许属性像字段那样使用,只是不允许作为ref或out参数值传递。ref和out参数内部要将内存地址传给目标方法。但由于属性可能是无支持字段的虚字段,也有可能只读或只写,所以不可能传递存储地址。同样的道理也适用于方法调用。如需将属性或方法调用作为ref或out参数值传递,首先必须将值拷贝到变量再传递该变量。方法调用结束后,再将变量的值赋回属性。
-
和实例字段不同,未初始化的静态字段将获得默认值(0,null,false等,即default(T)的结果,其中T是,类型名)。所以,没有显示赋值的静态字段也是可以访问的。
-
静态类不可以派生
-
“const”,常量字段自动成为静态字段,因为不需要为每个对象实例都生成新的字段实例。但将常量字段显示声明为static会造成编译错误。另外,常量字段通常只声明为有字面值的类型(string,int,double等)。Program或System.Guid等类型则不能用于常量字段。
-
嵌套类中的this成员引用嵌套类而非包容类的实例。嵌套类要访问包容类的实例,一个方案是显示传递包容类的实例,比如通过构造函数或方法参数。嵌套类另一个有趣的地方在于它能访问包容类的任何成员,其中包括私有成员。反之则不然,包容类不能访问嵌套类的私有成员。
-
分部方法必须返回void ,因为它可能只定义不实现,类似的,out参数在分部方法中不允许,因为out变量不用初始化,如果分部方法只定义不实现,就有可能出错,ref参数则没有问题
-
代码中的继承用于定义两个类的“属于”关系,派生类是对基类的特化
-
除非明确指定基类,否则所有类都默认从object派生
-
派生类型能隐式转型为它的基类。相反,基类向派生类的转换要求显示的转型操作符,因为转换可能失败。虽然编译器允许可能有效的显示转型,但“运行时”会坚持检查,无效转型将引发异常
-
基类的受保护成员只能从基类及其派生链的其他类中访问
-
虚暗示着实例,只有实例成员才可以是virtual的,所以static virtual方法毫无意义,编译器也不允许
-
用override修饰的任何方法自动为虚。只有基类的虚方法才能重写,所以重写后的方法还是虚方法
-
派生类不能访问基类的私有成员(内嵌派生类除外),基类的受保护成员只能从基类及其派生链的其他类中访问
-
抽象成员必须被重写,所以自动为虚,但不能用virtual关键字显示声明
-
C#不允许为接口成员使用访问修饰符,所有成员都自动公共,为public
-
接口的重点在于永远不能实例化,即不能用new创建接口
-
接口不能包含静态成员
-
由于显示接口实现直接和接口关联,所以没必要使用virtual,override,public来修饰他们,这些成员不能被视为类的公共成员,标注public有误导之嫌
-
隐式接口实现必须是public的。而virtual是可选的
-
除了string和object是引用类型,其他所有C#内建类型(比如bool和deciaml)都是值类型
-
除了属性和字段,结构体还可包含方法和构造函数,但不可包含用户自定义的默认(无参)构造函数。相反编译器自动生成默认构造函数将所有字段初始化为默认值。具体就是将引用类型的字段初始化为null,数值类型初始化为零,Boolean类型初始化为false
-
为确保局部值类型变量被构造函数完整初始化,结构中的每个构造函数都必须初始化结构的所有字段(和只读自动实现属性)
-
对于结构体,所有显示声明的字段都必须初始化
struct Angle
{
//public Angle(int degress, int minutes, int seconds)
//{
// Degrees = degress;
// Minutes = minutes;
// Seconds = seconds;
//}
public Angle(int degress, int minutes, int seconds)
{
_Degrees = degress;
_Minutes = minutes;
_Seconds = seconds;
}
public int Degrees { get { return _Degrees; } }
readonly private int _Degrees;
public int Minutes { get { return _Minutes; } }
readonly private int _Minutes;
public int Seconds { get { return _Seconds; } }
readonly private int _Seconds;
}
访问Degress会隐式访问this.Degress,但除非编译器知道所有字段都已初始化,否则访问this非法,考虑到结构体的字段初始化要求,简洁的C#6.0只读自动实现属性语法,以及“避免从包容属性外部访问字段”这一设计规范,所以从C#6.0起在结构体中应首选只读自动实现属性而非字段