2015-09-28 155 views
2

我想知道如何獲取任意類的字段的默認值。獲取一個字段的默認值

例如,

public class Example 
{ 
    public int a = 10; 
} 

我要當只給出typeof(Example)獲得價值10

這個默認值很有用,因爲我正在編寫一個函數來爲任何類型創建一個非空的默認實例。將實例初始化爲聲明中給出的值將會很好。

請注意,通過默認構造函數創建實例並獲取值不是我的選擇,因爲我希望我正在使用的函數可以應用於具有或不具有默認構造函數的類。

另外,DefaultValueAttribute也不適合我。據我所知,屬性只能有幾種類型作爲它的參數。所以我無法獲得自定義類型字段的默認值。

編輯1:

我知道這個問題似乎是Get default value of class member重複,但事實並非如此。在引用的問題中,OP滿意於使用構造函數來獲取類的實例。但就我而言,我無法確定我正在處理的類是否存在默認的構造函數。

我正在寫一個默認值生成器,因爲我需要一個任意類型的假對象。也就是說,沒有關於這種類型將會如何的假設。僞造的對象將通過GUI進行檢查,並且用戶可以編輯檢查器中暴露的字段的值。這裏的任意類型對我很重要,因爲檢查員不僅應該處理由我定義的類型,而且還處理庫中定義的類型。此外,虛假的對象不應該是空的或檢查員會炸燬,大聲笑。

FormatterServices.GetSafeUninitializedObject得到一個可以接受的假對象,因爲它分配內存塊並將它們初始化爲零。但是我覺得如果假對象可以進一步初始化,這樣字段可以在檢查器中顯示它們的默認值會更好。

感謝Patrick Hofman提醒我,我所說的「默認值」不是真正的默認值,而是一個將在構造函數中進行評估的表達式。這就是說,我仍然想知道是否有可能獲取字段初始化表達式和事件評估它。

我認爲應該有這樣做的方式,因爲反編譯器(如ILSpy)可以在反編譯結果中顯示字段初始值設定項。

+3

如果類型的構造函數分配另一個值會怎麼樣?那麼你的「默認」價值是毫無意義的。 –

+0

你能用嗎?(新的例子())。a,不是嗎? – enkryptor

+2

沒有創建類型的實例或像屬性那樣依賴元數據的做法沒有任何理智的方法。 – vcsjones

回答

3

您只能獲取常量的值,而不是任何其他類型的變量,因爲它們需要有一個初始化類來檢索一個值,這些值不再是實際的默認值,而只是當前值。

以前重複的Get default value of class member告訴你該怎麼做,如果你放棄不要創建實例約束。

這個呢?

public class Example 
{ 
    public readonly DateTime a = DateTime.Now; 
} 

你能告訴我這個字段的默認值是什麼嗎?即使可以,它也不是真正的默認值,它是某個時間點某個變量的評估值。

+3

最後一個例子中的默認值是'09/28/2015 16:07:08',不等#09/28/2015 16:07:20',沒有'09/28/2015 16:07:23'。 .. –

+0

你釘了它! @Jeppe –

1

您可以檢查IL代碼,並查找名爲.ctor(這些是實例構造函數)的成員。

然後找一個這確實call另一個Example::.ctor超載,而是調用基類的構造函數,你的情況[mscorlib]System.Object::.ctor()。 (如果不存在一個實例字段初始化不可達(病理情況下)!)

然後,該成員的IL內,現場作業stfld之前來電來人基類.ctor,是字段初始值設定項。瞧!

相關問題