DateTime有默认构造函数吗?
2007-02-22 11:39
204 查看
不知道你看到这个题目会不会很郁闷,但这的确是一个很值得考虑的问题。
你当然会说,这有啥,代码运行一下不就知道啦。
1
DateTime d = new DateTime();
编译虽然通过,但我们要考虑一下,这个d目前是什么值呢?
这就是一个很很值得考虑的问题。
我们知道,如果要声明一个DateTime新实例初始化为指定的年、月和日
使用如下的代码
1
DateTime d = new DateTime(2007,1,1);
那么,按一般我们对类的设计方法,DateTime的默认构造函数返回当前的日期实例比较合理。
但事实是
1
DateTime d = new DateTime();
2
System.Console.WriteLine(d);//0001-1-1 0:00:00
日期0001-1-1 0:00:00表示的是基督元年
1
DateTime d = new DateTime();
2
System.Console.WriteLine(d);//0001-1-1 0:00:00
3
System.Console.WriteLine(DateTime.MinValue);//0001-1-1 0:00:00
不过,事情到这里还没有结束,感觉上我们使用DateTime的默认构造函数产生了基督元年,但你去查一下DateTime的帮助,你会吓一跳,文档上根本没有声明过DateTime的默认构造函数。
DateTime的构造函数重载为下表
当然不是这样的,原因我们来逐步分析
DateTime的定义为:public struct DateTime
我们看到DateTime不是class,而是我们没有看到过的struct(结构)。
结构是一个和class非常接近的数据类型,我们来演示class和struct的区别
以下是对同一个现象描述的class和struct
1
public struct StockStruct
2
{
3
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
public string Name;
14
public string Code;
15
public double In;
16
public double Out;
17
}
我们分别实例化,代码的运行完全一样
1
StockStruct ss = new StockStruct();
2
System.Console.WriteLine(ss.Name);
3
StockClass sc = new StockClass();
4
System.Console.WriteLine(sc.Name);
我们为这两个数据类型添加默认构造函数
1
public struct StockStruct
2
{
3
/*结构不能包含显式的无参数构造函数
4
public StockStruct()
{
5
}
*/
6
public string Name;
7
public string Code;
8
public double In;
9
public double Out;
10
11
}
12
13
public class StockClass
14
{
15
public StockClass()
16
{
17
}
18
19
public string Name;
20
public string Code;
21
public double In;
22
public double Out;
23
}
我们发现不能为struct添加显式的无参数构造函数,这是为什么呢?简单的说,你可以这样理解:
class默认没有构造函数,当你一个构造函数都不写得时候,编译器会给你的类添加一个默认的构造函数。
struct天生有一个默认构造函数,该构造函数是由编译器统一控制,所以你就不能再为结构编写默认构造函数了。
我们再次修改我们的代码
1
public struct StockStruct
2
{
3
public StockStruct(string name,string code)
4
{
5
Name = name;
6
Code = code;
7
}
8
public string Name;
9
public string Code;
10
public double In;
11
public double Out;
12
13
}
14
15
public class StockClass
16
{
17
public StockClass(string name, string code)
18
{
19
Name = name;
20
Code = code;
21
}
22
23
public string Name;
24
public string Code;
25
public double In;
26
public double Out;
27
}
以上代码看似没有什么错误,但编译的结构再次让你感到沮丧。
class的代码被编译通过了,struct又有错误了
在控制离开构造函数之前,字段“StockStruct.In”必须完全赋值
在控制离开构造函数之前,字段“StockStruct.Out”必须完全赋值
该错误提示告诉我们,要么我们不给struct编写构造函数,编译器使用各数据类型的默认值,如果我们编写了构造函数,就必须在构造函数中为该struct的所有数据成员完全赋值。
这其实就是值类型和引用类型的一个区别:
值类型,要求在编译时知道对象的大小,引用类型可以推迟到运行时才知道对象的大小。
struct是值类型,因此又推导出另一个特征:struct没有析构函数。
1
public struct StockStruct : Object
2
{
3
public StockStruct(string name,string code)
4
{
5
Name = name;
6
Code = code;
7
In = 0;
8
Out = 0;
9
}
10
public string Name;
11
public string Code;
12
public double In;
13
public double Out;
14
15
}
16
17
public struct HKStock : StockStruct
18
{
19
20
}
上面的代码又错了,struct要求不能从其他类或结构继承,其他结构和类也不允许继承结构(结构天然的就是一个密封类型)。同时推导:struct 不能为 abstract,而应始终为隐式 sealed。
不过,结构仅可以支持接口,所以同时推导:结构成员无法声明为protected。
1
public struct StockStruct : System.IComparable
2
{
3
public StockStruct(string name, string code)
4
{
5
Name = name;
6
Code = code;
7
In = 0;
8
Out = 0;
9
}
10
public string Name;
11
public string Code;
12
public double In;
13
public double Out;
14
15
16
public int CompareTo(object obj)
17
{
18
return -1;
19
}
20
21
}
结构可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型。因为struct常用来做一个轻量级的类,快速的分配和快速的销毁,但这同时也失去了继承等能力。所以如果你需要类的所有特性,就还是使用类更好。
你当然会说,这有啥,代码运行一下不就知道啦。
1
DateTime d = new DateTime();
编译虽然通过,但我们要考虑一下,这个d目前是什么值呢?
这就是一个很很值得考虑的问题。
我们知道,如果要声明一个DateTime新实例初始化为指定的年、月和日
使用如下的代码
1
DateTime d = new DateTime(2007,1,1);
那么,按一般我们对类的设计方法,DateTime的默认构造函数返回当前的日期实例比较合理。
但事实是
1
DateTime d = new DateTime();
2
System.Console.WriteLine(d);//0001-1-1 0:00:00
日期0001-1-1 0:00:00表示的是基督元年
1
DateTime d = new DateTime();
2
System.Console.WriteLine(d);//0001-1-1 0:00:00
3
System.Console.WriteLine(DateTime.MinValue);//0001-1-1 0:00:00
不过,事情到这里还没有结束,感觉上我们使用DateTime的默认构造函数产生了基督元年,但你去查一下DateTime的帮助,你会吓一跳,文档上根本没有声明过DateTime的默认构造函数。
DateTime的构造函数重载为下表
当然不是这样的,原因我们来逐步分析
DateTime的定义为:public struct DateTime
我们看到DateTime不是class,而是我们没有看到过的struct(结构)。
结构是一个和class非常接近的数据类型,我们来演示class和struct的区别
以下是对同一个现象描述的class和struct
1
public struct StockStruct
2
{
3
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
public string Name;
14
public string Code;
15
public double In;
16
public double Out;
17
}
我们分别实例化,代码的运行完全一样
1
StockStruct ss = new StockStruct();
2
System.Console.WriteLine(ss.Name);
3
StockClass sc = new StockClass();
4
System.Console.WriteLine(sc.Name);
我们为这两个数据类型添加默认构造函数
1
public struct StockStruct
2
{
3
/*结构不能包含显式的无参数构造函数
4
public StockStruct()
{
5
}
*/
6
public string Name;
7
public string Code;
8
public double In;
9
public double Out;
10
11
}
12
13
public class StockClass
14
{
15
public StockClass()
16
{
17
}
18
19
public string Name;
20
public string Code;
21
public double In;
22
public double Out;
23
}
我们发现不能为struct添加显式的无参数构造函数,这是为什么呢?简单的说,你可以这样理解:
class默认没有构造函数,当你一个构造函数都不写得时候,编译器会给你的类添加一个默认的构造函数。
struct天生有一个默认构造函数,该构造函数是由编译器统一控制,所以你就不能再为结构编写默认构造函数了。
我们再次修改我们的代码
1
public struct StockStruct
2
{
3
public StockStruct(string name,string code)
4
{
5
Name = name;
6
Code = code;
7
}
8
public string Name;
9
public string Code;
10
public double In;
11
public double Out;
12
13
}
14
15
public class StockClass
16
{
17
public StockClass(string name, string code)
18
{
19
Name = name;
20
Code = code;
21
}
22
23
public string Name;
24
public string Code;
25
public double In;
26
public double Out;
27
}
以上代码看似没有什么错误,但编译的结构再次让你感到沮丧。
class的代码被编译通过了,struct又有错误了
在控制离开构造函数之前,字段“StockStruct.In”必须完全赋值
在控制离开构造函数之前,字段“StockStruct.Out”必须完全赋值
该错误提示告诉我们,要么我们不给struct编写构造函数,编译器使用各数据类型的默认值,如果我们编写了构造函数,就必须在构造函数中为该struct的所有数据成员完全赋值。
这其实就是值类型和引用类型的一个区别:
值类型,要求在编译时知道对象的大小,引用类型可以推迟到运行时才知道对象的大小。
struct是值类型,因此又推导出另一个特征:struct没有析构函数。
1
public struct StockStruct : Object
2
{
3
public StockStruct(string name,string code)
4
{
5
Name = name;
6
Code = code;
7
In = 0;
8
Out = 0;
9
}
10
public string Name;
11
public string Code;
12
public double In;
13
public double Out;
14
15
}
16
17
public struct HKStock : StockStruct
18
{
19
20
}
上面的代码又错了,struct要求不能从其他类或结构继承,其他结构和类也不允许继承结构(结构天然的就是一个密封类型)。同时推导:struct 不能为 abstract,而应始终为隐式 sealed。
不过,结构仅可以支持接口,所以同时推导:结构成员无法声明为protected。
1
public struct StockStruct : System.IComparable
2
{
3
public StockStruct(string name, string code)
4
{
5
Name = name;
6
Code = code;
7
In = 0;
8
Out = 0;
9
}
10
public string Name;
11
public string Code;
12
public double In;
13
public double Out;
14
15
16
public int CompareTo(object obj)
17
{
18
return -1;
19
}
20
21
}
结构可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型。因为struct常用来做一个轻量级的类,快速的分配和快速的销毁,但这同时也失去了继承等能力。所以如果你需要类的所有特性,就还是使用类更好。
相关文章推荐
- DateTime有默认构造函数吗?-class与struct的区别
- DateTime有默认构造函数吗?
- DateTime有默认构造函数吗?
- .Net JavaScriptSerializer处理DateTime的误解
- 深入Unix时间戳与C# DateTime时间类型互换的详解
- C++ 默认构造函数的构建
- 在java中实现日期类型和字符串类型的转换大全(Date String Timestamp Datetime)
- mysql语句中把string类型字段转datetime类型
- 如何將字串yyyyMMddHHmmss轉成Datetime呢?
- 默认构造函数
- 【零起点学通C++】构造函数与默认构造函数的代码及析构函数的相关笔记
- C#中 ACCESS数据库常用操作语句...容易出错的地方(DateTime类型)
- SQL 比较 两个 日期 (datetime) 的 年 月 大小,比较到年月,不比较日
- date 与datetime的区别
- C# DateTime 日期加1天 减一天 加一月 减一月 等方法
- 对C++默认构造函数的理解
- 诡异的问题“该字符串未被识别为有效的 DateTime”
- Java的默认构造函数调用
- No tag "datetimepicker" defined in tag library imported with prefix "s"
- DateTime类型常用处理