《.Net框架程序设计》读书笔记 之 常数 字段 方法
常数:
1.表示一个恒定不变的值的符号
2.常数总被认为成类型而非实例
3.必须能够在编译时确定他的值
4.当使用常数类型时,编译器首先从定义常数的模块的元数据中查找该符号,直接取出常数值然后嵌入到编译后的IL代码中,因此,常数在运行时不再需要任何内存分配,也不能获取常数地址,也不能以引用的方式来传递一个常数。
5.只有当确信一个符号的值永远不会改变时,才将其它义为常数。
6.只有基元类型才可以定义常数。Boolean,Char,Byte,SByte,Decimal,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double及String。另外,枚举类型由于本身以基元类型形式存储,也可以用来定义常数,虽然它并不是基元类型。
public Const Int MaxValue = 100;
字段:
1.字段又称数据成员,它保存着一个值类型的实例或者一个指向引用类型的引用。
2.CLR支持类型(静态)和实例(非静态)两种字段,对于类型字段,系统在该类型被加载进入一个应用程序域时为其动态分配内存;对于实例字段系统在该类型实例被构建时为其动态分配内存。
方法
1.创建一个引用类型实例时,系统首先为该实例分配内存,然后初始化对象的附加成员,最后调用类型的实例构造器设置对象的初始状态。
2.对于引用类型,有多少个构造器,就会初始化多少次定义的类型。
如果需要用到许多构造器,则应该避免在定义字段的时候就初始化而该在默认的构造器里初始化,然后其他的构造器显式地调用这个初始化构造器
4.可验证代码要求所有值类型在被读取之前首先进行初始化。
5. out ref
在值类型参数上使用out和ref关键字 与 用传值的方式来传递引用类型的参数在某种程序上具有相同的行为。 前种情况,out和ref关键字允许被调用方法直接操作一个值类型实例。调用代码必须为该实例分配内存,而被调用方法操作该内存; 后种情况,调用代码负责为引用类型对象分配内存,而被调用方法通过传入的引用(指针)来操作对象。
虚方法的版本问题:
1. vritual override
2.new 消除子类和父类中的同名方法歧义
3.子类调用父类中的同名方法用base关键字
1.表示一个恒定不变的值的符号
2.常数总被认为成类型而非实例
3.必须能够在编译时确定他的值
4.当使用常数类型时,编译器首先从定义常数的模块的元数据中查找该符号,直接取出常数值然后嵌入到编译后的IL代码中,因此,常数在运行时不再需要任何内存分配,也不能获取常数地址,也不能以引用的方式来传递一个常数。
5.只有当确信一个符号的值永远不会改变时,才将其它义为常数。
6.只有基元类型才可以定义常数。Boolean,Char,Byte,SByte,Decimal,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double及String。另外,枚举类型由于本身以基元类型形式存储,也可以用来定义常数,虽然它并不是基元类型。
public Const Int MaxValue = 100;
字段:
1.字段又称数据成员,它保存着一个值类型的实例或者一个指向引用类型的引用。
2.CLR支持类型(静态)和实例(非静态)两种字段,对于类型字段,系统在该类型被加载进入一个应用程序域时为其动态分配内存;对于实例字段系统在该类型实例被构建时为其动态分配内存。
方法
1.创建一个引用类型实例时,系统首先为该实例分配内存,然后初始化对象的附加成员,最后调用类型的实例构造器设置对象的初始状态。
2.对于引用类型,有多少个构造器,就会初始化多少次定义的类型。
class SomeType
{
int x = 5;
string s = "Hi,Welcome to you ";
Double d = 3.1415926;
Byte b;
public SomeType(){};
public SomeType(Int x){.};
public SomeType(string s){;;d = 10;};
}
//这里生产类SomeType的实例时将会三次初始化s x d,然后才将 执行 d = 10; ,因为里面有三个构造器
{
int x = 5;
string s = "Hi,Welcome to you ";
Double d = 3.1415926;
Byte b;
public SomeType(){};
public SomeType(Int x){.};
public SomeType(string s){;;d = 10;};
}
//这里生产类SomeType的实例时将会三次初始化s x d,然后才将 执行 d = 10; ,因为里面有三个构造器
如果需要用到许多构造器,则应该避免在定义字段的时候就初始化而该在默认的构造器里初始化,然后其他的构造器显式地调用这个初始化构造器
class SomeType
{
Int x;
string s;
Double d;
Byte b;
public SomeType()
{
x = 5;
s = "Hi,Welcome to you ";
d = 3.1415;
}
public SomeType(Int x) : this()//这里将调用默认的构造器
{
this.x = x;
}
public SomeType(string s) : this()
{
this.s = s;
}
}
3.C#不允许为一个值类型定义无参构造器,但CLR却允许,所以可用MSIL来为值类型定义无参构造器。因为不能定义无参构造器,所以值类型中不能在定义字段时同时初始化(内联)。{
Int x;
string s;
Double d;
Byte b;
public SomeType()
{
x = 5;
s = "Hi,Welcome to you ";
d = 3.1415;
}
public SomeType(Int x) : this()//这里将调用默认的构造器
{
this.x = x;
}
public SomeType(string s) : this()
{
this.s = s;
}
}
struct Point
{
public int x, y;
public Point()
{
x = y = 4;
}
}
class Rectangle
{
public Point left , right;
public Rectangle()
{..;}
}
//这种情况下,Point的两个字段left right的x 和y 将被初始化为什么呢?0还是4?
这里会编译报错,因为不能定义无参构造器。如果没有无参构造器,值类 型字段总是被初始为0或null.{
public int x, y;
public Point()
{
x = y = 4;
}
}
class Rectangle
{
public Point left , right;
public Rectangle()
{..;}
}
//这种情况下,Point的两个字段left right的x 和y 将被初始化为什么呢?0还是4?
4.可验证代码要求所有值类型在被读取之前首先进行初始化。
struct SomeValType
{
Int x, y;
public SomeValType(Int x)
{
this.x = x;//Y并没有初始化
}
}
//这里会编译通不过,会要求将SomeValType.y赋值
{
Int x, y;
public SomeValType(Int x)
{
this.x = x;//Y并没有初始化
}
}
//这里会编译通不过,会要求将SomeValType.y赋值
5. out ref
在值类型参数上使用out和ref关键字 与 用传值的方式来传递引用类型的参数在某种程序上具有相同的行为。 前种情况,out和ref关键字允许被调用方法直接操作一个值类型实例。调用代码必须为该实例分配内存,而被调用方法操作该内存; 后种情况,调用代码负责为引用类型对象分配内存,而被调用方法通过传入的引用(指针)来操作对象。
虚方法的版本问题:
1. vritual override
2.new 消除子类和父类中的同名方法歧义
3.子类调用父类中的同名方法用base关键字