[英]Returning a value type from a property
關於類中的值類型屬性,我對堆棧和堆上發生的事情感到困惑。
到目前為止我的理解:
當您創建具有如下結構(值類型)的類時:
class Foo
{
private Bar _BarStruct;
public Bar BarStruct
{
get {return _BarStruct; }
set {_BarStruct = value; }
}
}
private struct Bar
{
public int Number;
Bar()
{
Number = 1;
}
Bar(int i)
{
Number = i;
}
}
如果你像這樣創建一個類實例:
Foo fooObj = new Foo();
堆棧和堆將如下所示:
...其中 Bar 結構嵌入在堆中的 Foo 類中。 這對我來說很有意義,但是當我們考慮在 Foo 對象中修改 BarStruct 類中的 Number 整數時,我開始失去它。 例如:
Foo fooObj = new Foo();
fooObj.BarStruct.Number = 1;
據我了解,這應該返回一個 BarStruct 的副本以存在於堆棧中,這意味着 BarStruct 成員的任何更改都不會傳遞到對象,這就是上面最后一行給出錯誤的原因。
到目前為止,這是正確的嗎?
如果是這樣,我的問題是,怎么會有這樣的作業:
fooObj.BarStruct = new Bar(2);
...有效並更改堆值? 當然這只是改變堆棧上的值?? 此外,(漸漸地)我發現它非常令人困惑,以至於您可以在值類型上使用 new 。 對我來說,new 用於在堆上分配(按照 C++),並且為堆棧上的項目執行此操作感覺不自然。
所以只是重申這個問題,我假設當包含結構的屬性被調用時會發生什么,為什么你可以將一個新結構分配給一個副本,但它仍然改變堆上的引用?
真的希望這一切都有意義。
如果您需要澄清,請大喊大叫!
塔,
安迪。
看看這個作業:
fooObj.BarStruct = new Bar(2);
賦值不會改變堆棧上的值 - 它正在調用屬性的setter 。
換句話說,而您的第一個作業相當於:
fooObj.get_BarStruct().Number = 1; // Bad
第二個相當於:
fooObj.set_BarStruct(new Bar(2));
這有幫助嗎?
請注意,如果您使值類型一開始不可變,則有問題的分配將成為非問題 - 事實上,這通常有幫助。 可變值類型在 C# 中是一個非常糟糕的主意; 你可能會遇到無窮無盡的麻煩。
就您對“新”的期望而言 - 基本上盡量不要用 C++ 思考。 C# 不是 C++,如果您嘗試在 C# 中有效地編寫 C++,那么各種事情(析構函數、泛型、構造期間的行為)會讓您感到困惑。 “new”語句創建一個類型的新實例,無論是值類型還是引用類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.