13.2 结构是值类型

对于类而言,两个变量指向同一个对象的情况是存在的,因此对这样两个变量中的任意一个进行操作,其结果必然会影响另一个,因为它们指向的是同一个对象。这种情况对于结构而言是不可能发生的,结构是值类型,直接包含它自己的数据,每个结构都保存自己的一份数据,修改每一个结构的数据都不会对其他结构的数据造成影响。

如果从结构创建一个对象,并将该对象赋给某个变量,则该变量包含结构的全部值。复制类型为结构的变量时,将同时复制该结构所持有的所有数据。因此,对新副本所做的任何修改都不会对旧副本的数据产生影响。另外需要注意的是,由于结构不是引用类型,因此结构类型的变量不能被赋予null值。

接下来使用一段代码进行说明。首先定义两个类型:

❑结构类型:AddressBookEntry;

❑类:AddressBookEntryClass。

它们具有相同的字段成员:Name、MobilePhone、Birthday。在Main函数中,先定义两个AddressBookEntry类型的变量:entry和entry2,先对entry进行赋值,赋完值后将entry变量赋给entry2变量,然后对entry2的值进行修改,注意观察是否会影响到entry的值。

接下来,再定义两个AddressBookEntryClass类型的变量:entry3和entry4,步骤同上,对entry3赋值后再将entry3赋给entry4,然后对entry4的值进行修改,观察结果,如代码清单13-3所示。

代码清单13-3 结构是值类型


1 public struct AddressBookEntry//定义一个结构类型

2{

3 public string Name;

4 public string MobilePhone;

5 public DateTime Birthday;

6}

7

8 public class AddressBookEntryClass//定义一个类

9{

10 public string Name;

11 public string MobilePhone;

12 public DateTime Birthday;

13}

14

15 public class StructSample

16{

17 public static void Main()

18{

19 AddressBookEntry entry,entry2;//声明两个结构类型的变量

20 entry.Name="Tom";//赋值

21 entry.MobilePhone="1234567";

22 entry.Birthday=DateTime.Parse("2000-1-1 12:12:12");

23

24//将entry赋给entry2,然后修改entry2,注意观察看是否会

25//影响entry的数据

26 entry2=entry;

27 entry2.Name="Jerry";

28 entry2.MobilePhone="7654321";

29 entry2.Birthday=DateTime.Parse("2010-1-1 10:10:10");

30

31 AddressBookEntryClass entry3,entry4;

32 entry3=new AddressBookEntryClass();

33 entry3.Name="Tom";

34 entry3.MobilePhone="1234567";

35 entry3.Birthday=DateTime.Parse("2000-1-1 12:12:12");

36

37//将entry3赋给entry4,然后修改entry4,注意观察看是否会

38//影响entry的数据

39 entry4=entry3;

40 entry4.Name="Jerry";

41 entry4.MobilePhone="7654321";

42 entry4.Birthday=DateTime.Parse("2010-1-1 10:10:10");

43

44 System.Console.WriteLine(“姓名:{0} 手机:{1} 生日:{2}”,entry.Name,entry.MobilePhone,entry.Birthday);

45 System.Console.WriteLine(“姓名:{0} 手机:{1} 生日:{2}”,entry2.Name,entry2.MobilePhone,entry2.Birthday);

46

47 System.Console.WriteLine(“姓名:{0} 手机:{1} 生日:{2}”,entry3.Name,entry3.MobilePhone,entry3.Birthday);

48 System.Console.WriteLine(“姓名:{0} 手机:{1} 生日:{2}”,entry4.Name,entry4.MobilePhone,entry4.Birthday);

49}

50}


上述代码的运行结果为:


姓名:Tom 手机:1234567 生日:2000-1-1 12:12:12

姓名:Jerry 手机:7654321 生日:2010-1-1 10:10:10

姓名:Jerry 手机:7654321 生日:2010-1-1 10:10:10

姓名:Jerry 手机:7654321 生日:2010-1-1 10:10:10


从结果可以看出,对entry2值的修改并未影响到entry的值,而对entry4的修改让entry4和entry3的值变得相同,这说明每个结构类型存储的都是自己的数据,在将一个结构类型的变量赋给另一个结构类型的变量的时候,CLR执行的是将数据复制过去的策略。而类则不同,类是引用类型,entry3和entry4保存的都是指向数据对象的引用,并且它们指向的是同一个对象,因此对entry4的修改也对entry3的数据产生了直接的影响。我们使用图示进行说明,如图13-1所示。

13.2 结构是值类型 - 图1

图 13-1 结构是值类型