[英]Can you have a class in a struct?
在C#中是否可以使用具有類型類型的成員變量的Struct? 如果是這樣,信息存儲在哪里,堆棧,堆,或兩者?
是的你可以。 指向類成員變量
的指針
與結構的其余值一起存儲
在堆棧中
,類實例的數據存儲在堆上。
結構也可以包含類定義作為成員(內部類)。
這是一些真正無用的代碼,至少編譯並運行以顯示它是可能的:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyStr m = new MyStr();
m.Foo();
MyStr.MyStrInner mi = new MyStr.MyStrInner();
mi.Bar();
Console.ReadLine();
}
}
public class Myclass
{
public int a;
}
struct MyStr
{
Myclass mc;
public void Foo()
{
mc = new Myclass();
mc.a = 1;
}
public class MyStrInner
{
string x = "abc";
public string Bar()
{
return x;
}
}
}
}
類內容存儲在堆上。
對類的引用(與指針幾乎相同)與struct內容一起存儲。 存儲結構內容的位置取決於它是局部變量,方法參數還是類的成員,以及它是否被閉包裝箱或捕獲。
of a class object or else a null referece. 如果結構的某個字段是類類型,則該字段將保留類對象的 ,或者保留null引用。 如果所討論的類對象是不可變的(例如string
),則存儲其標識也將有效地存儲其內容。 . 但是,如果所討論的類對象是可變的,那么存儲該標識將是一種有效的存儲內容的方法, 。
通常,應避免在結構中存儲可變類類型,除非以下兩種情況之一適用:
請注意,場景#1在泛型類型中非常常見; 例如,有一個字典的“值”是可變對象的身份是很常見的; 枚舉該字典將返回KeyValuePair
的實例,其Value
字段包含該可變類型。
場景#2不太常見。 沒有辦法告訴編譯器除了屬性設置器之外的結構方法將修改結構,因此在只讀上下文中應禁止它們的使用; 一個可以有一個行為類似於List<T>
,但是具有值語義,並且包含一個Add
方法,但是嘗試在只讀結構實例上調用Add
會產生偽代碼而不是編譯器錯誤。 此外,這種結構上的變異方法和屬性設定器通常表現得相當差。 當這些結構作為一個不可變的包裝器存在於其他可變類中時,它們可能是有用的; 如果這樣的結構永遠不會被裝箱,那么性能往往比一個類好。 如果只裝箱一次(例如通過鑄造到接口類型),性能通常可以與一個類別相比。 如果重復加框,性能可能比一類差。
這可能不是推薦的做法:請參閱http://msdn.microsoft.com/en-us/library/ms229017(VS.85).aspx
引用類型在堆上分配,內存管理由垃圾收集器處理。
值類型在堆棧或內聯中分配,並在超出范圍時釋放。
通常,值類型分配和釋放更便宜。 但是,如果它們用於需要大量裝箱和拆箱的場景,則與參考類型相比,它們的性能很差。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.