首页 > Linux操作系统 > Linux操作系统 > 【笔记】C# 中的知识点小结
1 const 和 readonly
在多数情况下可以混用。本质区别在于,const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值。而static readonly是在运行时计算出其值的,所以还可以通过静态构造函数来赋值。
1. static readonly MyClass myins = new MyClass();
2. static readonly MyClass myins = null;
3. static readonly B = 10; static readonly A = B * 20;
4. static readonly int [] constIntArray = new int[] {1, 2, 3};
5. void SomeFunction()
{
const int a = 10;
...
}
6.private static string astr="abcd";
private const string str = astr+"efg";
1:不可以换成const。new操作符是需要执行构造函数的,所以无法在编译期间确定
2:可以换成const。我们也看到,Reference类型的常量(除了String)只能是Null。
3:可以换成const。我们可以在编译期间很明确的说,A等于200。
4:不可以换成const。道理和1是一样的,虽然看起来1,2,3的数组的确就是一个常量。
5:不可以换成readonly,readonly只能用来修饰类的field,不能修饰局部变量,也不能修饰property等其他类成员。
6.错误:如果在astr前加上const或者const改为readonly即可;
总结:1.const、readonly和static readonly定义的常量,指定初始值后(包括在构造函数内指定的初始值) 将不可更改,可读不可写;
2.const定义时必须指定初始值,而readonly定义时可以不进行初始化(MS建议在定义时初始值),同时也可以在构造函数内指定初始值, 并以构造函数内指定的值为准;
3.const和static readonly定义的常量是静态的,只能由类直接访问;而readonly定义的常量是非静态 的,只能由实例对象访问;
4.static readonly常量,如果在构造函数内指定初始值,则必须是静态无参构造函数;
5.const是编译时常量,readonly是运行时常量;cosnt较高效,readonly较灵活。在应用上以static readonly代替const,以平衡const在灵活性上的不足,
同时克服编译器优化cosnt性能,所带来的程序集引用不一致问题;
2 new, virtual, abstract, sealed, override
new
new 关键字可以显式隐藏从基类继承的成员。隐藏继承的成员意味着该成员的派生版本将替换基类版本。也就说在使用派生类的方法是调用的方法是New关键字新定义出来的方法,而不是基类的方法。
在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。使用 new 显式隐藏成员会取消此警告,并记录代之以派生版本这一事实。
Virtual
Virtual 关键字允许在派生类中重写这些对象,默认情况下,方法是非虚拟的,不可以重写非虚方法,virtual关键字不可以与static、abstract、private、override一起使用。
Virtual关键字又是和override紧密不可分的,如果要实现Virtual方法就必须要使用override或new关键字(new和override产生的机理不同)。
abstract
在类声明中使用abstract修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。抽象类不能实例化。
抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。
sealed
密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写。密封类不能被继承。
当应用于方法或属性时,sealed修饰符必须始终与override一起使用。
Override
Override关键字主要是提供派生类对基类方法的新实现,重写的基类方法必须和Override的方法具有相同的签名
3 字段 局部变量 属性
字段是属于一个类的,在类中定义(注意:是类中,而不是类中的某个方法或属性中),也就是说它的作用域是整个类。
局部变量是属于一个函数或语句块的,它的作用域是从定义开始,到离开语句块。
一个属性 = 一个(通常私有)字段 + 一到二个方法(取值方法和赋值方法)
字段可以有静态的,但是属性必须是实例的,其实有些属性能实现的功能,字段也能实现,但是不鼓励用字段来实现,因为OOP的一个原则就是数据封装,意味着我们不应该将字段的类型以公开的方式提供给外界。
还有一些原因,例如我们可能希望访问一个字段的同时执行一些额外的操作,或者缓存某个数值,或者延迟创建某个内部对象。
我们也可能希望对字段的访问是线程安全的。或者字段可能只是一个逻辑表示,其真正的值并不是以字节的形式存放在内存中,而是通过某种算法计算得来的
所以建议将所有的字段访问限制为私有
4 异常处理
异常可以由公共语言运行库 (CLR)、第三方库或使用 throw 关键字的应用程序代码生成。异常由遇到错误的代码引发,由能够更正错误的代码捕捉。一旦引发了一个异常,这个异常就会在调用堆栈中往上传播,直到找到针对它的 catch 语句。
在执行 catch 块之前,将检查由运行库评估过的 try 块(包括包含兼容的 catch 块的 try 块)中是否有 finally 块。Finally 块允许程序员清理中止的 try 块可能留下的任何不明确状态,或释放任何外部资源(如图形句柄 DB连接或文件流),而不用等待运行库中的垃圾回收器来完成这些对象。
异常用于指示在运行程序时发生了错误。此时将创建一个描述错误的异常对象,然后使用throw关键字“引发”该对象。然后运行库搜索最兼容的异常处理程序。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23155850/viewspace-662322/ ,如需转载,请注明出处,否则将追究法律责任。