摘要:[C#]結構
Interduction
我們很常用 class 來做事,可是卻忘了 struct 的存在,結構由於被設計成為實值型別,所以在效率上的表現要比類別來的出色,
如只提供儲存數值資料功能,使用類別就顯得浪費了。結構也可以建立各種成員,例如建構式、常數、欄位、方法、屬性、索引子、運算子、事件和巢狀型別等等,若要弄得這麼複雜,將失去使用結構型別的意義。結構很有彈性,建立結構物件可以不需要使用 new 關鍵字,他有專屬的預設建構式;當然你也可以自己打造建構式,而建立物件的時候必須透過 new 關鍵字,引用此建構式。
Reference
HOW TO:在結構之間實作使用者定義的轉換 (C# 程式設計手冊 與類別比較
結構宣告內不能初始化欄位,除非將其宣告為 const 或 static。
結構不可宣告預設建構函式 (沒有參數的建構函式) 或解構函式。
結構無法繼承自類別或其他結構。
結構是在指派時複製的。當指派結構給新變數時,就會複製所有資料,而新變數所做的任何修改都不會變更原始複本的資料。
結構為實值型別,而類別則是參考型別。
與類別不同的是,結構不需使用 new 運算子就能執行個體化
結構可以宣告含有參數的建構函式。
結構無法從另一個結構或類別繼承而來,且它不能成為類別的基底。所有結構都是從繼承自 System.Object 的 System.ValueType 直接繼承而來
結構可實作介面
結構可以用來當做可為 Null 的型別,而且可以對其指派 null 值。
Example
using System; class UsingStruct { static void Main(string[] args) { ClassStruct theClassStruct;
theClassStruct.student = "三小俠";
theClassStruct.stuNumber = "20051212001"; Console.WriteLine( "學生:" + theClassStruct.student + "\t" +
"學號:" + theClassStruct.stuNumber ); ClassStruct theClassStruct1 = new ClassStruct("馬小九", "20010105002"); Console.WriteLine( "學生:" + theClassStruct1.student + "\t" +
"學號:" + theClassStruct1.stuNumber ); Console.ReadLine(); } } public struct ClassStruct { public string student; public string stuNumber; public ClassStruct(string student, string stuNumber) {
this.student = student;
this.stuNumber = stuNumber; } } |
執行結果:
學生:三小俠 學號:20051212001
學生:馬小九 學號:20010105002
注意事項:
結構無法繼承自類別或其他結構 ,可是,結構卻可以實做介面,
所以在結構裡面不可使用,protected 與 internal protected 存取修飾子;若是實做介面,也是使用 public 修飾子。
以下是測試:
namespace dog { internal struct TestStruct { private string _Name; private int _Number; private float _Price; private double _Water; internal float Price { get { return _Price; } set { _Price = value; } } internal string GetName() { return _Name; } //這邊編譯錯誤 protected int GetNumber() { return _Number; } //這邊編譯錯誤 internal protected double GetWater(){ return _Water; } } }
補充 :
1。結構繼承介面
先定義一個介面
namespace ClassLibrary1 { internal interface Interface1 { string MethodB(); } }
再來定義一個結構並且繼承介面
namespace ClassLibrary1 { public struct ClassStructTest : Interface1{ public string MethodB() { return "MethodB"; } } }
Client 端程式碼
class Program { static void Main(string[] args) { //建立結構物件 ClassLibrary1.ClassStructTest oStruct = new ClassLibrary1.ClassStructTest(); Console.WriteLine(oStruct.MethodB()); Console.ReadKey(); } }
輸出結果
延伸閱讀 :
[C#]Effective C# 條款六: 明辨值類型與參考類型的使用場合 - Level Up- 點部落
[C#]Effective C# 條款七: 將值類型盡可能實現為具有常量性與原子性的類型 - Level Up- 點部落
原文參考呂文達研究室
三小俠 小弟獻醜,歡迎指教