不知道你看到这个题目会不会很郁闷,但这的确是一个很值得考虑的问题。
你当然会说,这有啥,代码运行一下不就知道啦。
1

DateTime d = new DateTime();
编译虽然通过,但我们要考虑一下,这个d目前是什么值呢?
这就是一个很很值得考虑的问题。
我们知道,如果要声明一个DateTime新实例初始化为指定的年、月和日
使用如下的代码

DateTime d = new DateTime(2007,1,1);
那么,按一般我们对类的设计方法,DateTime的默认构造函数返回当前的日期实例比较合理。
但事实是

DateTime d = new DateTime();
2

System.Console.WriteLine(d);//0001-1-1 0:00:00
日期0001-1-1 0:00:00表示的是基督元年


3

System.Console.WriteLine(DateTime.MinValue);//0001-1-1 0:00:00
不过,事情到这里还没有结束,感觉上我们使用DateTime的默认构造函数产生了基督元年,但你去查一下DateTime的帮助,你会吓一跳,文档上根本没有声明过DateTime的默认构造函数。
DateTime的构造函数重载为下表
<a>DateTime (Int64)</a>
<a>DateTime (Int64, DateTimeKind)</a>
<a>DateTime (Int32, Int32, Int32)</a>
<a>DateTime (Int32, Int32, Int32, Calendar)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32, Calendar)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32, DateTimeKind)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32, Int32)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32, Int32, Calendar)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32, Int32, DateTimeKind)</a>
<a>DateTime (Int32, Int32, Int32, Int32, Int32, Int32, Int32, Calendar, DateTimeKind)</a>
的的确确没有默认构造函数,是不是写文档的人不仔细把默认构造函数忘记描述了呢?
当然不是这样的,原因我们来逐步分析
DateTime的定义为:public struct DateTime
我们看到DateTime不是class,而是我们没有看到过的struct(结构)。
结构是一个和class非常接近的数据类型,我们来演示class和struct的区别
以下是对同一个现象描述的class和struct
struct常用来做一个轻量级的类,快速的分配和快速的销毁,但这同时也失去了继承等能力。所以如果你需要类的所有特性,就还是使用类更好。

public struct StockStruct
{
4
public string Name;
5
public string Code;
6
public double In;
7
public double Out;
8
9
}
10

11

public class StockClass
12
13
14
15
16
17
我们分别实例化,代码的运行完全一样

StockStruct ss = new StockStruct();

System.Console.WriteLine(ss.Name);

StockClass sc = new StockClass();

System.Console.WriteLine(sc.Name);
我们为这两个数据类型添加默认构造函数

/*结构不能包含显式的无参数构造函数
public StockStruct()
{
*/


public StockClass()
18
19
20
21
22
23
我们发现不能为struct添加显式的无参数构造函数,这是为什么呢?简单的说,你可以这样理解:
class默认没有构造函数,当你一个构造函数都不写得时候,编译器会给你的类添加一个默认的构造函数。
struct天生有一个默认构造函数,该构造函数是由编译器统一控制,所以你就不能再为结构编写默认构造函数了。
我们再次修改我们的代码

public StockStruct(string name,string code)
Name = name;
Code = code;


public StockClass(string name, string code)
24
25
26
27
以上代码看似没有什么错误,但编译的结构再次让你感到沮丧。
class的代码被编译通过了,struct又有错误了
在控制离开构造函数之前,字段“StockStruct.In”必须完全赋值
在控制离开构造函数之前,字段“StockStruct.Out”必须完全赋值
该错误提示告诉我们,要么我们不给struct编写构造函数,编译器使用各数据类型的默认值,如果我们编写了构造函数,就必须在构造函数中为该struct的所有数据成员完全赋值。
这其实就是值类型和引用类型的一个区别:
值类型,要求在编译时知道对象的大小,引用类型可以推迟到运行时才知道对象的大小。
struct是值类型,因此又推导出另一个特征:struct没有析构函数。

public struct StockStruct : Object
In = 0;
Out = 0;


public struct HKStock : StockStruct
{
上面的代码又错了,struct要求不能从其他类或结构继承,其他结构和类也不允许继承结构(结构天然的就是一个密封类型)。同时推导:struct 不能为 abstract,而应始终为隐式 sealed。
不过,结构仅可以支持接口,所以同时推导:结构成员无法声明为protected。

public struct StockStruct : System.IComparable
public StockStruct(string name, string code)
public int CompareTo(object obj)
return -1;
结构可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型。因为
本文转自shyleoking 51CTO博客,原文链接:http://blog.51cto.com/shyleoking/806257