![](/img/trans.png)
[英]Deserializing object[] that contains primitive types and one class type
[英]Object Class Primitive Types Stack and Heap
首先,如果聽起來太愚蠢,我道歉。 但我總是發現自己提出以下問題。
由於對象類是.Net中所有類的最終基類,而類是引用類型,引用類型存儲在堆上,因此甚至可以進入堆棧。 我知道原始類型存儲在堆棧中,這就是我感到困惑的地方。
以int32為例,如果它的一個類及其基類是object,那么它的引用類型應該在堆上。 怎么去堆疊。
如果它不是一個類,那么我們怎么能這樣做
int i = 1;
object obj = i;
既然我做不了類似的事情
int i = 1;
MyClass myObj = i;
編輯
從我得到的答案來看,int是結構而不是類。 仍然令人困惑的是值類型的基類是如何引用類型(對象)而它的值類型不是引用類型。
另一點是“屬於類的值類型不會存儲在堆棧中”,我想一切都在類中,甚至是控制台程序中的Main方法。 對我來說,這意味着所有變量都以某種方式屬於一個類? 那他們怎么去堆疊?
首先,如果聽起來太愚蠢,我道歉。 但我總是發現自己提出以下問題。
這些是非常常見的問題。
由於對象類是.Net中所有類的最終基類,而類是引用類型,引用類型存儲在堆上,因此甚至可以進入堆棧。
你很困惑很多事情。 讓我們從:
好的,現在我們知道有三種東西,其中兩種是價值觀。
現在讓我們正確陳述你的句子:
對象類是.NET中所有類的最終基類。 類的所有實例都是引用類型的實例。 引用類型的所有實例都存儲在堆上。 如何存儲在堆棧中?
現在我們正確地提出了問題,答案很明確。 值類型的 引用和實例可以進入堆棧。
讓我們繼續。
我知道原始類型存儲在堆棧中,這就是我感到困惑的地方。
從你的詞匯中消除“原始類型”這個詞; 這毫無意義。 讓我們改寫一下:
我知道值類型的實例存儲在堆棧中
不,你不知道 ,因為為了算作知識 ,陳述必須是真的。 那句話是錯誤的。 值存儲在變量中。 變量要么是長壽命的,要么是短命的。 短期變量在堆棧上。 長期存在的變量在堆上。
以int32為例,如果它的一個類及其基類是object,那么它的引用類型應該在堆上。
Int32不是一個類。 這是一個結構。 它不是參考類型。
仍然令人困惑的是值類型的基類是如何引用類型(對象)而它的值類型不是引用類型。
瑪麗是個母親。 她是女性。 她的孩子也都是女性嗎?
怎么去堆疊。
當整數存儲在短期變量中時,整數在堆棧上。
當引用存儲在短期變量中時,引用將進入堆棧。
值是引用還是值類型的實例是無關緊要的; 重要的是變量存在多長時間 ?
如果它不是一個類,那么我們怎么能這樣做
int i = 1;
object obj = i;
好問題。 生成一個特殊類。 認為這是:
class BoxedInt
{
int value;
public BoxedInt(int v) { this.value = v; }
public int Unbox() { return this.value; }
}
那么你的程序片段是:
int i = 1;
object obj = new BoxedInt(i);
接着
int j = (int)obj;
是相同的
int j = ((BoxedInt)obj).Unbox();
另一點是“屬於類的值類型不會存儲在堆棧中
更好的說法是:引用類型的字段是長期存在的變量。 因此它們存儲在堆上。
我想一切都在一個類中,甚至是控制台程序中的Main方法。
是的,所有代碼都在類或結構中。
對我來說,這意味着所有變量都以某種方式屬於一個類?
不,局部變量不是類的成員。
我住在一個黃色的房子里。 因此里面的所有物體都是黃色的嗎?
那他們怎么去堆疊?
普通方法中的局部變量是短暫的,因此它會進入堆棧。
只需停止將堆棧視為與存儲的數據類型有關。 堆棧與存儲什么類型的數據無關。 想想變量 。 堆棧是短期變量的地方。 堆是長壽命變量的地方。 變量的類型無關緊要。
Int32
是ValueType,因此它將在堆棧中分配。 關鍵字int
指的是struct System.Int32
。
.net中的value types
分為value types
和reference types
。
值類型是堆棧分配或在結構中內聯分配。
引用類型是堆分配的 。
值類型包括兩個主要類別:
引用和值類型都是從最終基類Object
派生的。
如果值類型必須像對象一樣運行,則在堆上分配使值類型看起來像引用對象的包裝器,並將值類型的值復制到其中。 標記包裝器,以便系統知道它包含值類型。 此過程稱為裝箱,反向過程稱為拆箱。
請參考這里
原始數據類型是值類型,它們的大小是在編譯時定義的,因此編譯器將它們推送到堆棧以便更快地訪問,而引用類型只是指向存儲在堆上的對象的起始地址的指針,並且它的內存未在編譯時分配(已分配)在運行時)。
你不能這樣做
int i = null; // Because it's value type and need some value
(Default is 0) here int is alias to Int32 which is structure and
structure is value type and same is for other primitives
System.Object
類型不是“類”,但System.Object
類型的實例是引用類型。 B
繼承自類型A
, 唯一隱含的是B
獲取A
的所有public
或protected
非靜態方法,屬性和事件。 基本上,值類型在內存中可以有兩種不同的表示(盒裝和非盒裝),而引用類型在內存中只有一種表示。
首先,你絕對可以這樣做:
int i = 1;
MyClass myObj = i;
只需將MyClass
定義為:
class MyClass
{
int i;
public MyClass(int i)
{
this.i = i;
}
public static implicit operator MyClass(int i)
{
return new MyClass(i);
}
}
(請注意,在此示例中,類MyClass
的字段i
是堆分配的,即使它是值類型)
其次,值類型不一定存儲在堆棧中,如下所示:
class
值類型字段 現在,當類型B
繼承自類型A
,這意味着只有 B
獲取A
的所有properties
, methods
和events
。 它沒有規定如何分配B
實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.