C# 对象和类型总结(五)

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#高级编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值