2010-09-14 64 views
5

在c#中,我可以使用default(T)來獲取類型的默認值。我需要在運行時從System.Type獲取默認類型。我怎樣才能做到這一點?如何使用類型調用default(T)?

例如沿此線的東西(不工作)

var type = typeof(int); 
var defaultValue = default(type); 

回答

9

對於參考類型返回null,對於值類型,您可以嘗試使用Activator.CreateInstance或調用該類型的默認構造函數。

public static object Default(Type type) 
{ 
    if(type.IsValueType) 
    { 
     return Activator.CreateInstance(type); 
    } 

    return null; 
} 
+1

寫了我的問題後不久,我想出了'return Expression。 Lambda >(Expression.Convert(Expression.Default(type),typeof(object)))。Compile()();',但你的更好。 – GiddyUpHorsey 2010-09-14 09:08:40

+0

@Giddy:這將是一種非常昂貴的方式,因爲您在每次調用時都將表達式樹編譯爲IL(然後JIT將不得不將其編譯爲本機)。 – 2010-09-14 17:29:11

+0

是的,我同意。這就是爲什麼我不使用它,而是使用madgnome的解決方案。雖然,這是更短,更易讀的代碼,而不是性能,這促使我使用他的。對於我的場景,性能不是太大。 – GiddyUpHorsey 2010-09-14 22:20:08

6

如果你想建立一個表達式樹,使用Expression.Default

Expression expression = Expression.Default(type); 

另外一個方式,你可以這很容易將是:

object defaultValue = Array.CreateInstance(type, 1).GetValue(0); 

醜陋,但它會工作:)注意,它是很難得到一個可空類型的默認值,因爲它會將方框裝入空引用。

正如在評論中指出,有一些模糊的情況下(void和指針類型),其中,這些是不等價的,但他們是極端情況:)

+1

我生成與思維空間光速使用表達式樹,但其查詢供應商不支持'DefaultExpression',所以我需要的實際值,以把'ConstantExpression'內。 – GiddyUpHorsey 2010-09-14 09:11:31

+0

最細微的挑剔,behviour是不同的指針類型。 'default(int *)'返回'IntPtr.Zero',而'Default(typeof(int *))'拋出。我發現的另一個隱晦的地方是'System.Void',你不能做'default(void)',而'Default(typeof(void))'返回null。沒有biggie,以防萬一任何人想照顧.. – nawfal 2016-07-05 12:44:51

+0

@nawfal:增加了一個注意到這個效果,謝謝。 – 2016-07-05 12:51:02

3

這是很容易的,你只需有2例考慮:

  • 引用類型:默認值始終是空
  • 值類型:您可以輕鬆地創建使用Activator.CreateInstance

    實例

你也可以考慮使用FormatterServices.GetUninitializedObject而不是Activator.CreateInstance,它可能會更快。

+0

你有沒有試過運行你的代碼?它不會工作,原因是值類型不(通常)有一個默認的構造函數。他們用C#做,但它是一個虛構的;在CLR級別上沒有,IL中使用'initobj'。 – 2010-09-14 09:01:17

+0

@Pavel,你是對的,我從來沒有意識到,沒有一個真正的默認構造函數......我將其更改爲Activator.CreateInstance,並且它工作正常 – 2010-09-14 09:07:22

相關問題