C#基礎(chǔ)語法:結(jié)構(gòu)和類區(qū)別詳解
結(jié)構(gòu)和類很相似,也可以包含數(shù)據(jù)成員和函數(shù)成員,但是與類不同,結(jié)構(gòu)是一種值類型,(我們可以理解為一種特殊的值類型所以不存在繼承的問題)為其分配數(shù)據(jù)不需要從托管堆中分配存儲器。結(jié)構(gòu)類型的變量直接包含了該結(jié)構(gòu)的數(shù)據(jù),而類類型的變量所包含的只是對相應(yīng)對象的一個(gè)引用。
下面總結(jié)一下結(jié)構(gòu)和類的不同:
1.結(jié)構(gòu)是值類型,對結(jié)構(gòu)類型的變量賦值將創(chuàng)建所賦值的一個(gè)副本。
2.結(jié)構(gòu)實(shí)例的默認(rèn)值不是null,而是具有默認(rèn)值的初始值。
3.在結(jié)構(gòu)和類中this的意義不一樣。
4.結(jié)構(gòu)不支持繼承(所以結(jié)構(gòu)成員的聲明可訪問性不能是protected,protected internal,結(jié)構(gòu)中的函數(shù)成員不能是abstract 或者virtual,所以在結(jié)構(gòu)中override修飾符只適用于重寫從System.ValueType繼承的方法)但是可以實(shí)現(xiàn)接口。
5.在結(jié)構(gòu)中實(shí)例字段聲明中不能含有變量的初始值設(shè)定項(xiàng)
6.在結(jié)構(gòu)中不能聲明無參數(shù)的實(shí)例構(gòu)造函數(shù)。
7.在結(jié)構(gòu)中不能聲明析構(gòu)函數(shù)。
測試區(qū)別特性代碼:
using System; namespace StructAndClass { struct SPoint { public int x, y; public SPoint(int x, int y) { this.x = x; this.y = y; } } class CPoint { public int x, y; public CPoint(int x, int y) { this.x = x; this.y = y; } } class Test { public static void Main() { SPoint sp1 = new SPoint(2, 5); Console.WriteLine("結(jié)構(gòu)/sp1初始值:"); Console.WriteLine("sp1.x={0}", sp1.x); SPoint sp2 = sp1; Console.WriteLine("sp1=sp2后:"); Console.WriteLine("sp1.x={0}"); Console.WriteLine("sp1.x={0}", sp1.x); Console.WriteLine("sp2.x={0}", sp2.x); sp1.x = 5; Console.WriteLine("再次改變sp1的值后:"); Console.WriteLine("sp1.x={0}", sp1.x); Console.WriteLine("sp2.x={0}", sp2.x); Console.WriteLine("============================"); CPoint cp1 = new CPoint(2,5); Console.WriteLine("類/cp1初始值:"); Console.WriteLine("cp1.x={0}", cp1.x); CPoint cp2 = cp1; Console.WriteLine("cp1=cp2后:"); Console.WriteLine("cp1.x={0}", cp1.x); Console.WriteLine("cp2.x={0}", cp2.x); cp1.x = 5; Console.WriteLine("再次改變cp1的值后:"); Console.WriteLine("cp1.x={0}", cp1.x); Console.WriteLine("cp2.x={0}", cp2.x); Console.ReadKey(); } } }
對于結(jié)構(gòu),即使沒有new運(yùn)算符聲明的結(jié)構(gòu)變量也是有效的,結(jié)構(gòu)雖然不能聲明無參數(shù)的實(shí)力構(gòu)造函數(shù),但是它其實(shí)隱式的包含了一個(gè)無參數(shù)的構(gòu)造函數(shù):而且在結(jié)構(gòu)的所有字段沒有明確賦值之前,不能調(diào)用結(jié)構(gòu)的實(shí)例函數(shù)成員。在結(jié)構(gòu)的構(gòu)造函數(shù)中應(yīng)該給所有的字段賦值。例如:
struct DC { public int x, y; public int X { set { x = value; } get { return x; } } public int Y { set { y = value; } get { return y; } } public DC(int x,int y) { this.x = x; this.y = y; } } struct RDC { public int x, y; public int X { set { x = value; } get { return x; } } public int Y { set { y = value; } get { return y; } } public RDC(int x, int y) { this.x = x; this.y = y; } } class Test { public static void Main() { DC dc=new DC(); dc.x = 3; dc.y = 5; Console.WriteLine("已經(jīng)對x,y初始化后:"); Console.WriteLine("此時(shí)可以訪問和修改dc.X={0}的值",dc.X); Console.WriteLine("我在這里創(chuàng)建了一個(gè)DC的復(fù)制結(jié)構(gòu)RDC/n并且不對x,y初始化就會報(bào)錯(cuò)"); RDC rdc; rdc.y = 5;//可以編譯通過 rdc.X = 3;//這里就會出錯(cuò),不能編譯通過 Console.WriteLine("=======test over================"); } }
在結(jié)構(gòu)的實(shí)例構(gòu)造函數(shù)內(nèi),this 相當(dāng)于一個(gè)結(jié)構(gòu)類型的 out 參數(shù),(必須在內(nèi)部對它明確賦值)而在結(jié)構(gòu)的實(shí)例函數(shù)成員內(nèi),this 相當(dāng)于一個(gè)結(jié)構(gòu)類型的 ref 參數(shù)。在這兩種情況下,this 本身相當(dāng)于一個(gè)變量,因而有可能對該函數(shù)成員調(diào)用所涉及的整個(gè)結(jié)構(gòu)進(jìn)行修改(如對 this 賦值,或者將 this 作為 ref 或 out 參數(shù)傳遞)。例如:(引用上面的例子)
struct DC { public int x, y; public int X { set { x = value; } get { return x; } } public int Y { set { y = value; } get { return y; } } public DC(int x,int y) { X= x;//這里就是錯(cuò)的 Y = y;//會提示沒有給this對象的所有字段賦值 } }
相關(guān)文章
c# Invoke和BeginInvoke 區(qū)別分析
這篇文章主要介紹了c# Invoke和BeginInvoke 區(qū)別分析,需要的朋友可以參考下2014-10-10C#畫筆使用復(fù)合數(shù)組繪制單個(gè)矩形的方法
這篇文章主要介紹了C#畫筆使用復(fù)合數(shù)組繪制單個(gè)矩形的方法,涉及C#使用畫筆繪制圖形的相關(guān)技巧,需要的朋友可以參考下2015-06-06C#實(shí)現(xiàn)的上傳圖片、保存圖片、加水印、生成縮略圖功能示例
這篇文章主要介紹了C#實(shí)現(xiàn)的上傳圖片、保存圖片、加水印、生成縮略圖功能,結(jié)合實(shí)例形式較為詳細(xì)的分析了C#圖片上傳、保存、水印、縮略圖等相關(guān)操作技巧,需要的朋友可以參考下2019-02-02基于C#實(shí)現(xiàn)的仿windows左側(cè)伸縮菜單效果
這篇文章主要介紹了基于C#實(shí)現(xiàn)的仿windows左側(cè)伸縮菜單效果,比較實(shí)用的功能,需要的朋友可以參考下2014-08-08C#中面向?qū)ο缶幊虣C(jī)制之多態(tài)學(xué)習(xí)筆記
這篇文章主要介紹了C#中面向?qū)ο缶幊虣C(jī)制之多態(tài)學(xué)習(xí)筆記,本文總結(jié)了個(gè)人對多態(tài)的理解以及接口多態(tài)、繼承多態(tài)等內(nèi)容,并給出了代碼示例,需要的朋友可以參考下2015-01-01c#基礎(chǔ)知識---委托,匿名函數(shù),lambda
這篇文章主要介紹了c# 委托,匿名函數(shù),lambda的相關(guān)知識,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06