C#中結(jié)構(gòu)類型和類類型在語(yǔ)法上非常相似,他們都是一種數(shù)據(jù)結(jié)構(gòu),都可以包括數(shù)據(jù)成員和方法成員。
結(jié)構(gòu)和類的區(qū)別:
- 結(jié)構(gòu)是值類型,它在棧中分配空間;
類是引用類型,它在堆中分配空間,棧中保存的只是引用。 - 結(jié)構(gòu)類型直接存儲(chǔ)成員數(shù)據(jù);
類的數(shù)據(jù)位于對(duì)中,位于棧中的變量保存的是指向堆中數(shù)據(jù)對(duì)象的引用。
C#中的簡(jiǎn)單類型,如int、double、bool等都是結(jié)構(gòu)類型。如果需要的話,甚至可以使用結(jié)構(gòu)類型結(jié)合運(yùn)算符運(yùn)算重載,再為C#語(yǔ)言創(chuàng)建出一種新的值類型來。
由于結(jié)構(gòu)是值類型,并且直接存儲(chǔ)數(shù)據(jù),因此在一個(gè)對(duì)象的主要成員為數(shù)據(jù)且數(shù)據(jù)量不大的情況下,使用結(jié)構(gòu)會(huì)帶來更好的性能。
public struct AddressBook
{
//字段、屬性、方法、事件
}
對(duì)于類而言,兩個(gè)變量指向同一個(gè)對(duì)象的情況是存在的,因此對(duì)這樣兩個(gè)變量中的任意一個(gè)進(jìn)行操作,起結(jié)果必然會(huì)影響另外一個(gè),因?yàn)樗鼈冎赶虻氖峭粋€(gè)對(duì)象。
結(jié)構(gòu)是值類型,直接包含它自己的數(shù)據(jù),每個(gè)結(jié)構(gòu)都保存自己的一份數(shù)據(jù),修改每一個(gè)結(jié)構(gòu)的數(shù)據(jù)都不會(huì)對(duì)其他結(jié)構(gòu)的數(shù)據(jù)造成影響。
<pre><code>
public class Program
{
static void Main(string[] args)
{
PersonStruct p1, p2; //與類一樣,但可以不new
p1.Name = "張飛";
p1.MobilePhone = "13553663108";
p1.Birthday = DateTime.Now.AddYears(-10);
p2 = p1; //將p1的值賦給p2 //由于是值類型,因此賦值等于將全部值全部復(fù)制到p2的??臻g
p2.Name = "關(guān)羽"; //然后修改p2的值看是否會(huì)影響p1
Console.WriteLine(p1.Name); //輸出 張飛 沒影響
PersonClass p3 = new PersonClass();
p3.Name = "張飛";
p3.MobilePhone = "13553663108";
p3.Birthday = DateTime.Now.AddYears(-10);
PersonClass p4 = new PersonClass();
p4 = p3; //將p3的值賦給p4 賦值后,由于是引用類型,因此兩個(gè)對(duì)象指向的是同一個(gè)地址(堆空間)
p4.Name = "關(guān)羽"; //然后修改p4的值看是否會(huì)影響p3
Console.WriteLine(p3.Name); //輸出 關(guān)羽 沒影響
Console.ReadKey();
}
}
public class PersonClass
{
public string Name;
public string MobilePhone;
public DateTime Birthday;
}
public struct PersonStruct
{
public string Name;
public string MobilePhone;
public DateTime Birthday;
}
</code></pre>
將一個(gè)結(jié)構(gòu)變量賦值給另一個(gè)結(jié)構(gòu)變量,就是把數(shù)據(jù)從一個(gè)結(jié)構(gòu)復(fù)制到另一個(gè)結(jié)構(gòu)。而類則不同,在類的變量之間,復(fù)制的是引用,而不是類數(shù)據(jù)。。因此當(dāng)數(shù)據(jù)比較大的時(shí)候,這種數(shù)據(jù)復(fù)制機(jī)制會(huì)帶來較大的開銷。