c#学习笔记 017 (匿名类型、结构)

2008年12月29日星期一

c#学习笔记 017 (匿名类型、结构)

一、匿名类型。

var和new一起使用可以创建匿名类型。匿名类型只是一个继承了Object的,没有名称的类。例如:

var captain=new{FirstName="James",MiddleName="T",LastName="Kirk"};

如果创建第二个对象:

var docter=new{FirstName="Leonard",MiddleName="",LastName= "McCoy"};

captain和doctor的类型就是相同的。例如:可以设置caption=doctor。

这些对象的类型名是未知的。编译器为类型“伪造”了一个名称,但只有编译器才能使用它,我们不能也不应使用新对象上的任何引用类型,因为这不会得到一致的结果。

二、结构。

当声明一个小的数据结构,而且对性能要求较高时,最好使用结构而不是类。例如:

class Dimensions
{
public double Length;
public double Width;
}

可以声明为结构:

struct Dimensions
{
public double Length;
public double Width;
}

为结构定义函数与为类定义函数完全相同,下面的代码演示了结构的构造函数和属性:

struct Dimensions
{
public double Length;
public double Width;

Dimensions(double length,double width)
{
Length=length;
Width=width;
}

public double Diagonal
{
get
{
return Math.Sqrt(Length*Length+Width*Width);
}
}
}

在许多方面可以将结构看做是缩小的类,与类基本相同,但更适合把数据组合起来,与类的区别是:

1、结构是值类型,存储在堆栈中,如果是另一个类的一部分则存储为内联,生存周期同其他简单数据类型一致。

2、结构不支持继承。

3、编译器总是提供一个默认构造函数,并不能替换(重写)这个默认构造函数。

4、使用结构可以指定字段如何在内存中布局。

另外,类的字段按照编程规则应当除了const字段外全部声明为私有的,并用属性访问封装。而结构的字段往往全是public的,

注意:在c++中,类和结构都是是相同的对象。

结构是值类型,但在语法上可以把它们当成类来处理,例如:

Dimensions point = new Dimensions();

point.Length=3;

point.Width=6;

由于结构并不分配在堆中所以,new关键字只是初始值。对于结构也可以这样写:

Dimensions point;

point.Length=3;

point.Width=6;

如果这样对待一个类,就会发生编译错误:

如果象下面这样使用结构同样会发生一个未初始化的错误:

Dimensions point;

Double D=point.Length;

如果结构定义为类的成员字段,在初始化对象使,结构就初始化为0。

结构是值类型,使用得好会提升程序性能,反之也会降低程序性能。

一方面,为结构分配内存时速度非常快,结构超出作用域后删除的也非常快。

另一方面,把结构作为参数传递或者把结构赋给另一个结构,结构中所有内容被复制,对于类只复制引用,这样就会有性能损失(相对于类),损失的状况于结构的大小相关,结构一般用于小的数据结构,如果当参数传递,就应当用ref参数传递,避免性能损失。

结构和继承

结构不能继承,唯一的例外是结构派生于类System.Object。所以结构也可以访问System.Object的方法。在结构中甚至可以重写System.Object中的方法。结构派生于System.ValueType,System.ValueType派生于System.Object,System.ValueType并未提供任何新成员,只是提供了更适合结构的执行代码,不能为结构提供任何其他基类,结构只能派生于ValueType

结构的构造函数

定义方式于类相同,但不允许无参数的构造函数。原因隐藏在.net运行库的执行方式中:在极少数情况下.net运行库不能调用用户提供的无参数构造函数(结构里),但为了这种极少数情况的发生(它往往是无法预测的),Microsoft 目前采取的是简单的处理方法——不允许c#的结构使用无参数的构造函数。

默认构造函数把字段初始化为0,总是这样,不能采用给字段赋初始值的方法绕过默认构造函数,下面的写法会报错:

struct Dimensions
{
public double Length=1;
public double Width=2;
}

当然,类中可以这么做。

另外,可以为结构提供Close()或Dispose()方法。

    0 评论:

    发表评论