1、只读字段
常量的概念是一个包含不能够修改单的值的变量,常量是C#与大多数编程语言共有的。readonly关键字比const灵活得得多,允许把一个字段设置为常量,但还需要执行一些技术以确定其初始值。其规则是可在构造范中给只读字段复制,但不能再其他地方赋值。只读只读可为一个实例字段,不是静态字段,类的每个实例可以有不同的值。与const字段不同,如果要把只读字段设置为静态,则必须显式声明它。
2、匿名类型
var与new关键字一起使用,可以创建匿名类型匿名类型只是一个继承自Object且没有名称的类。该类的定义从初始化器中推断,类似于隐式类型化的变量。如果需要一个对象包含某个人的姓氏、中间名和名字,则声明如下:
var captain=new {FirstName="James",MiddleName="T",LastName="Kirk"};
创建另一个对象,
var doctor=new {FirstName="Leonard",MiddleName="",LastName="McCopy"};
captain和doctor类型相同。例如:可以设置captain=doctor。
如果所设置的值来自于另一个对象,则可简化为初始值。如果已经有一个包含FirstName、MiddleName和LastName属性的类,且有该类的一个实例(person),captain对象就可以初始化为:
var captain=new {person.FirstName,person.MiddleName,person.LastName};
person对象的属性名应投射到对象名captain.所以captain 对象应有FirstName、MiddleName和LastName属性。
3、结构
结构定义函数与类定义函数完全相同。
struct Dimensions
{
public double Length;
public double Width;
public Dimensions(double length,double width)
{
Length=length;
Width=width;
}
public double Diagonal
{
get
{
return Math.Sqrt(Length*Length + Width*Width);
}
}
}
结构是值类型,不是引用类型。它们存储在栈中或存储为(inline)(如果它们是存储在栈中的另一个对象的一部分),其生存期的限制与简单的数据类型一样。
1)结构不支持继承;
2)对于结构,构造函数的工作函数有一些的区别。尤其是编译器总是提供一个无参数的默认构造函数,它是不允许替换的;
3)使用结构,可以指定字段如何在内存中布局;
结构实际上是把数据项组合在一起,有时大多数或者全部字段声明为public。严格来说,这鱼编写的.NET代码的规则相反——根据Microsoft,字段(除了const字段之外)应总是私有的,并由公有属性封装。但是,对于简单的结构,许多开发人员都认为公有字段是可接收的编程方式。
(1) 结构是值类型
结构是值类型,但在语法上常常可以把它们当作类来处理。上述定义Dinmensions类的定义,其可编写下面的代码:
Dimensions point=new Dimensions();
point.Length=3;
point.Width=6;
注意:因结构是值类型,所以new运算符与类和其他引用类型的工作方式不同。new运算符并不分配堆中的内存,而是只调用相应的构造函数,根据传送给它的参数,初始化所有的字段。对于结构,可编写下述完全合法的代码:
Dimensions point;
point.Length=3;
point.Width=6;
结构遵循其他数据类型都遵循的规则:在使用前所有的元素都必须进行初始化。在结构上调用new运算符,或者给所有的字段分布赋值,结构就完全初始化。
(2) 结构和继承
结构不是为继承设计的。通常,它不能从一个结果中继承。唯一的例外是对应的结构(和C#中的其他类型一样)最终派生于类System.Object。结构也可以访问System.Object的方法。在结构中,甚至可以重写System.Object中的方法——如重写ToString()方法。结构的继承链是:每个结构派生自System.ValueType类,System.ValueType类又派生自System.Object。ValudeType并没有给Object添加任何新成员,但提供一些更适合的结构的实现方式。
注意:不能够为结构提供其他基类:每个结构都派生自ValueType。
(3) 结构的构造函数
结构定义构造函数的方式与为类定义构造函数的方式相同,但不允许定义无参数的构造函数。
静止在C#的结构类使用无参数的构造函数。
默认构造函数把数值字段都初始化为0,把引用类型字段初始化为null,且总是隐式德给出,即使提供其他带参数的构造函数。提供字段的初始值也不能绕过默认构造函数。下面代码编译会出错:
struct Dimensions
{
public double Length=1; //error. Initial values not allowed
public double Width=2; //error. Initial values not allowed
}
(4) 弱引用
弱引用允许创建和使用对象,但是垃圾回收器允许时,就会回收对象并释放内存。由于存在潜在的bug和性能问题,一般不会这么做,但是在特定的情况下使用弱引用是很合理的。
弱引用是使用WeakReference类创建的。对象可能在任意时刻被回收,所以在引用该对象前必须确认它存在。在引用该对象前必须确认它存在。
static void Main()
{
//Instantiate a weak reference to MathTest object
WeakReference mathReference =new WeakReference(new MathTest());
MathTest math;
if(mathReference.IsAlive)
{
math=mathReference.Target as MathTest;
math.Value=30;
Console.WriteLine("Valude field of math varible contains "+math.Value);
Console.WriteLine("Square of 30 is " + math.GetSquare());
}
else
{
Console.WriteLine("Reference is not available");
}
GC.Collect();
if(mathReference.IsAlive)
{
math=mathReference.Target as MathTest;
}
else
{
Console.WriteLine("Refernece is not available.");
}
}
参考
C#高级编程