《.Net框架程序设计》读书笔记 之 常数 字段 方法

该博客为转载内容,转载自https://www.cnblogs.com/sunsjorlin/archive/2005/11/18/279534.html ,涉及C#相关知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常数:
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.对于引用类型,有多少个构造器,就会初始化多少次定义的类型。

None.gifclass SomeType
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif   
int x = 5;
InBlock.gif   
string s = "Hi,Welcome to you ";
InBlock.gif   Double d 
= 3.1415926;
InBlock.gif   Byte b;
InBlock.gif   
ExpandedSubBlockStart.gifContractedSubBlock.gif   
public SomeType()dot.gif{};
ExpandedSubBlockStart.gifContractedSubBlock.gif   
public SomeType(Int x)dot.gif{dot.gif.};
ExpandedSubBlockStart.gifContractedSubBlock.gif   
public SomeType(string s)dot.gif{dot.gif;dot.gif;d = 10;};
ExpandedBlockEnd.gif}

None.gif
//这里生产类SomeType的实例时将会三次初始化s x d,然后才将 执行  d = 10;  ,因为里面有三个构造器

如果需要用到许多构造器,则应该避免在定义字段的时候就初始化而该在默认的构造器里初始化,然后其他的构造器显式地调用这个初始化构造器
None.gifclass SomeType
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif   Int x;
InBlock.gif   
string s;
InBlock.gif   Double d;
InBlock.gif   Byte b;
InBlock.gif
InBlock.gif   
public SomeType()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      x 
= 5;
InBlock.gif      s 
= "Hi,Welcome to you ";
InBlock.gif      d 
= 3.1415;
ExpandedSubBlockEnd.gif   }

InBlock.gif   
public SomeType(Int x) : this()//这里将调用默认的构造器
ExpandedSubBlockStart.gifContractedSubBlock.gif
   dot.gif{
InBlock.gif      
this.x = x;
ExpandedSubBlockEnd.gif   }

InBlock.gif   
public SomeType(string s) : this()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
this.s = s;
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}
3.C#不允许为一个值类型定义无参构造器,但CLR却允许,所以可用MSIL来为值类型定义无参构造器。因为不能定义无参构造器,所以值类型中不能在定义字段时同时初始化(内联)。
None.gifstruct Point
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif   
public int x, y;
InBlock.gif   
public Point()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      x 
= y = 4;
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif
class Rectangle
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif   
public Point left , right;
InBlock.gif   
public Rectangle()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{dot.gif..;}
ExpandedBlockEnd.gif}

None.gif
//这种情况下,Point的两个字段left  right的x 和y 将被初始化为什么呢?0还是4? 
这里会编译报错,因为不能定义无参构造器。如果没有无参构造器,值类 型字段总是被初始为0或null.
4.可验证代码要求所有值类型在被读取之前首先进行初始化。
None.gifstruct SomeValType
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif   Int x, y;
InBlock.gif   
public SomeValType(Int x)
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
this.x = x;//Y并没有初始化
ExpandedSubBlockEnd.gif
   }

ExpandedBlockEnd.gif}

None.gif
//这里会编译通不过,会要求将SomeValType.y赋值

5. out    ref   
在值类型参数上使用out和ref关键字 与 用传值的方式来传递引用类型的参数在某种程序上具有相同的行为。    前种情况,out和ref关键字允许被调用方法直接操作一个值类型实例。调用代码必须为该实例分配内存,而被调用方法操作该内存; 后种情况,调用代码负责为引用类型对象分配内存,而被调用方法通过传入的引用(指针)来操作对象。



虚方法的版本问题:
1. vritual override
2.new 消除子类和父类中的同名方法歧义
3.子类调用父类中的同名方法用base关键字

转载于:https://www.cnblogs.com/sunsjorlin/archive/2005/11/18/279534.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值