C#基礎(chǔ)教程之類class與結(jié)構(gòu)struct的區(qū)別
一、類class
類class是引用類型,可以直接賦值為null,默認(rèn)值也是null
XClass xClass = null;//語(yǔ)法正確
一般來(lái)說(shuō),某個(gè)類對(duì)象使用另一個(gè)類的對(duì)象賦值時(shí),則兩者共用一個(gè)內(nèi)存地址【節(jié)約內(nèi)存空間】,ReferenceEquals引用比較此時(shí)返回true
XClass xClass3 = new XClass() { Id = 7, Name = "天晴之海" }; XClass xClass4 = xClass3;
類的構(gòu)造函數(shù)(構(gòu)造方法)
如果一個(gè)類沒(méi)有顯示定義構(gòu)造函數(shù),則默認(rèn)有一個(gè)無(wú)參構(gòu)造函數(shù),
如果一個(gè)類已定義了帶參數(shù)的構(gòu)造函數(shù),如果不手動(dòng)定義無(wú)參構(gòu)造函數(shù),則沒(méi)有無(wú)參構(gòu)造函數(shù)
特殊類String:
特殊類【字符串String】雖然是引用類型,但對(duì)字符串的更新并不會(huì)修改字符串的原實(shí)際值,
字符串作為參數(shù)傳遞并不能篡改原來(lái)的值,
可以認(rèn)為字符串雖然是引用類型,但使用時(shí)按值類型處理
二、結(jié)構(gòu)struct
結(jié)構(gòu)struct是值類型,不能直接賦值為null,結(jié)構(gòu)的默認(rèn)值為0,false,類型名稱字符串等
XStruct xStruct=null;//語(yǔ)法錯(cuò)誤,不能為值類型賦值為null
如果想為值類型賦值為null,請(qǐng)使用可空類型Nullable<T>
public struct Nullable<T> where T : struct
比如如下代碼即可編譯通過(guò):
Nullable<XStruct> xStruct = null;//可空值類型
或者簡(jiǎn)化為
XStruct? xStruct = null;//可空值類型的簡(jiǎn)化
某個(gè)結(jié)構(gòu)對(duì)象使用另一個(gè)結(jié)構(gòu)的對(duì)象賦值時(shí),則兩者的內(nèi)存地址完全不同,第二個(gè)結(jié)構(gòu)對(duì)象新開(kāi)一個(gè)內(nèi)存空間,只不過(guò)內(nèi)存的值完全一致【內(nèi)存空間增加】,ReferenceEquals引用比較此時(shí)返回false
結(jié)構(gòu)的構(gòu)造函數(shù)
所有結(jié)構(gòu)都自動(dòng)繼承抽象值類型基類ValueType,有個(gè)默認(rèn)無(wú)參構(gòu)造函數(shù)ValueType(),因此無(wú)法在自定義結(jié)構(gòu)中定義無(wú)參構(gòu)造函數(shù)
using System.Runtime.InteropServices; using System.Security; namespace System { // // 摘要: // 為值類型提供基類。 [ComVisible(true)] public abstract class ValueType { // // 摘要: // 初始化 System.ValueType 類的新實(shí)例。 protected ValueType(); // // 摘要: // 指示此實(shí)例與指定對(duì)象是否相等。 // // 參數(shù): // obj: // 要與當(dāng)前實(shí)例進(jìn)行比較的對(duì)象。 // // 返回結(jié)果: // 如果 true 和該實(shí)例具有相同的類型并表示相同的值,則為 obj;否則為 false。 [SecuritySafeCritical] public override bool Equals(object obj); // // 摘要: // 返回此實(shí)例的哈希代碼。 // // 返回結(jié)果: // 一個(gè) 32 位帶符號(hào)整數(shù),它是此實(shí)例的哈希代碼。 [SecuritySafeCritical] public override int GetHashCode(); // // 摘要: // 返回此實(shí)例的完全限定類型名稱。 // // 返回結(jié)果: // 完全限定的類型名稱 public override string ToString(); } }
值類型重寫了Equals方法,如果一個(gè)值類型的具體屬性值完全一致時(shí),兩個(gè)對(duì)象是相等的
三、測(cè)試控制臺(tái)應(yīng)用程序GenericTemplateDemo:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GenericTemplateDemo { class Program { static void Main(string[] args) { Console.SetWindowSize(120, 30); Console.WriteLine($"結(jié)構(gòu)的默認(rèn)值為類型名(一定不為null):{default(XStruct)},類型名為【{typeof(XStruct)}】"); Console.WriteLine($"類的默認(rèn)值為null?【{default(XClass) == null}】"); Console.WriteLine("---------------------------------結(jié)構(gòu)的Equal比較---------------------------------"); XStruct xStruct1 = new XStruct() { Id = 5, Name = "ABC" }; XStruct xStruct2 = new XStruct("ABC") { Id = 5 }; Console.WriteLine($"結(jié)構(gòu)一的內(nèi)容{{Id:{xStruct1.Id},Name:{xStruct1.Name}}}"); Console.WriteLine($"結(jié)構(gòu)二的內(nèi)容{{Id:{xStruct2.Id},Name:{xStruct2.Name}}}"); Console.WriteLine(); Console.WriteLine($"比較兩個(gè)結(jié)構(gòu)的實(shí)例值是否相等:{xStruct1.Equals(xStruct2)}"); Console.WriteLine($"比較兩個(gè)結(jié)構(gòu)的引用是否指向同一個(gè)實(shí)例:{ReferenceEquals(xStruct1, xStruct2)}"); XStruct xStruct3 = new XStruct("修吾") { Id = 8 }; XStruct xStruct4 = xStruct3; Console.WriteLine($"結(jié)構(gòu)三的內(nèi)容{{Id:{xStruct3.Id},Name:{xStruct3.Name}}}"); Console.WriteLine($"結(jié)構(gòu)四的內(nèi)容{{Id:{xStruct4.Id},Name:{xStruct4.Name}}}"); Console.WriteLine(); Console.WriteLine($"比較兩個(gè)結(jié)構(gòu)的實(shí)例值是否相等:{xStruct3.Equals(xStruct4)}"); Console.WriteLine($"比較兩個(gè)結(jié)構(gòu)的引用是否指向同一個(gè)實(shí)例:{ReferenceEquals(xStruct3, xStruct4)}"); Console.WriteLine("---------------------------------類的Equal比較---------------------------------"); XClass xClass1 = new XClass() { Id = 6, Name = "毒瘴泉" }; XClass xClass2 = new XClass("毒瘴泉") { Id = 6 }; Console.WriteLine($"類一的內(nèi)容{{Id:{xClass1.Id},Name:{xClass1.Name}}}"); Console.WriteLine($"類二的內(nèi)容{{Id:{xClass2.Id},Name:{xClass2.Name}}}"); Console.WriteLine(); Console.WriteLine($"比較兩個(gè)類的實(shí)例值是否相等:{xClass1.Equals(xClass2)}"); Console.WriteLine($"比較兩個(gè)類的引用是否指向同一個(gè)實(shí)例:{ReferenceEquals(xClass1, xClass2)}"); Console.WriteLine(); XClass xClass3 = new XClass() { Id = 7, Name = "天晴之海" }; XClass xClass4 = xClass3; Console.WriteLine($"類三的內(nèi)容{{Id:{xClass3.Id},Name:{xClass3.Name}}}"); Console.WriteLine($"類四的內(nèi)容{{Id:{xClass4.Id},Name:{xClass4.Name}}}"); Console.WriteLine(); Console.WriteLine($"比較兩個(gè)類的實(shí)例值是否相等:{xClass3.Equals(xClass4)}"); Console.WriteLine($"比較兩個(gè)類的引用是否指向同一個(gè)實(shí)例:{ReferenceEquals(xClass3, xClass4)}"); Console.ReadLine(); } } /// <summary> /// 測(cè)試用的結(jié)構(gòu),結(jié)構(gòu)繼承ValueType,而ValueType重寫了Equals(object obj)方法,因此比較 /// 結(jié)構(gòu)不允許顯式定義無(wú)參的構(gòu)造函數(shù),因 結(jié)構(gòu)struct一經(jīng)定義,自動(dòng)會(huì)生成一個(gè)無(wú)參構(gòu)造函數(shù) /// </summary> struct XStruct { public XStruct(string name) { Id = 0; Name = name; } public int Id { get; set; } public string Name { get; set; } } /// <summary> /// 測(cè)試用的類 /// </summary> class XClass { public XClass() { } public XClass(string name) { Id = 0; Name = name; } public int Id { get; set; } public string Name { get; set; } } }
四、程序運(yùn)行如圖:
補(bǔ)充:結(jié)構(gòu)與類的區(qū)別
1.類和結(jié)構(gòu)有以下幾個(gè)基本的不同點(diǎn):
- 類是引用類型,結(jié)構(gòu)是值類型。
- 結(jié)構(gòu)不支持繼承。
- 結(jié)構(gòu)不能聲明默認(rèn)的構(gòu)造函數(shù)。
- 結(jié)構(gòu)體中聲明的字段無(wú)法賦予初值,類可以
- 類的對(duì)象是存儲(chǔ)在堆空間中,結(jié)構(gòu)存儲(chǔ)在棧中。
2.選擇使用情況
堆空間大,但訪問(wèn)速度較慢,棧空間小,訪問(wèn)速度相對(duì)更快。當(dāng)我們描述一個(gè)輕量級(jí)對(duì)象的時(shí)候,結(jié)構(gòu)可提高效率,成本更低。不過(guò)假如我們?cè)趥髦档臅r(shí)候希望傳遞的是對(duì)象的引用地址而不是對(duì)象的拷貝,就應(yīng)該使用類了。
總結(jié)
到此這篇關(guān)于C#基礎(chǔ)教程之類class與結(jié)構(gòu)struct區(qū)別的文章就介紹到這了,更多相關(guān)C# 類class與結(jié)構(gòu)struct區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
picturebox加載圖片的三種方法與網(wǎng)站驗(yàn)證碼的抓取
這篇文章主要介紹了picturebox加載圖片的三種方法與網(wǎng)站驗(yàn)證碼的抓取,需要的朋友可以參考下2015-03-03C#調(diào)用QQ_Mail發(fā)送郵件實(shí)例代碼兩例
這篇文章介紹了C#調(diào)用QQ_Mail發(fā)送郵件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04C#實(shí)現(xiàn)鬧鐘AlarmClock實(shí)例代碼
這篇文章主要介紹了C#實(shí)現(xiàn)鬧鐘AlarmClock實(shí)例代碼,很實(shí)用的功能,需要的朋友可以參考下2014-08-08VS2010寫的程序在自己電腦可以運(yùn)行、其他電腦上不能運(yùn)行的解決方案
自己用Visual Studio 2010 旗艦版寫了一個(gè)軟件,在自己電腦上運(yùn)行完全沒(méi)有問(wèn)題,但是拷貝到其他人電腦上之后不管雙擊還是以管理身份運(yùn)行,均沒(méi)有反應(yīng),進(jìn)程管理器中相關(guān)進(jìn)程也只是一閃而過(guò)2013-04-04