在c#中,我可以使用default(T)
來獲取類型的默認值。我需要在運行時從System.Type
獲取默認類型。我怎樣才能做到這一點?如何使用類型調用default(T)?
例如沿此線的東西(不工作)
var type = typeof(int);
var defaultValue = default(type);
在c#中,我可以使用default(T)
來獲取類型的默認值。我需要在運行時從System.Type
獲取默認類型。我怎樣才能做到這一點?如何使用類型調用default(T)?
例如沿此線的東西(不工作)
var type = typeof(int);
var defaultValue = default(type);
對於參考類型返回null
,對於值類型,您可以嘗試使用Activator.CreateInstance
或調用該類型的默認構造函數。
public static object Default(Type type)
{
if(type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
如果你想建立一個表達式樹,使用Expression.Default
:
Expression expression = Expression.Default(type);
另外一個方式,你可以做這很容易將是:
object defaultValue = Array.CreateInstance(type, 1).GetValue(0);
醜陋,但它會工作:)注意,它是很難得到一個可空類型的默認值,因爲它會將方框裝入空引用。
正如在評論中指出,有一些模糊的情況下(void
和指針類型),其中,這些是不等價的,但他們是極端情況:)
我生成與思維空間光速使用表達式樹,但其查詢供應商不支持'DefaultExpression',所以我需要的實際值,以把'ConstantExpression'內。 – GiddyUpHorsey 2010-09-14 09:11:31
最細微的挑剔,behviour是不同的指針類型。 'default(int *)'返回'IntPtr.Zero',而'Default(typeof(int *))'拋出。我發現的另一個隱晦的地方是'System.Void',你不能做'default(void)',而'Default(typeof(void))'返回null。沒有biggie,以防萬一任何人想照顧.. – nawfal 2016-07-05 12:44:51
@nawfal:增加了一個注意到這個效果,謝謝。 – 2016-07-05 12:51:02
這是很容易的,你只需有2例考慮:
值類型:您可以輕鬆地創建使用Activator.CreateInstance
你也可以考慮使用FormatterServices.GetUninitializedObject
而不是Activator.CreateInstance
,它可能會更快。
你有沒有試過運行你的代碼?它不會工作,原因是值類型不(通常)有一個默認的構造函數。他們用C#做,但它是一個虛構的;在CLR級別上沒有,IL中使用'initobj'。 – 2010-09-14 09:01:17
@Pavel,你是對的,我從來沒有意識到,沒有一個真正的默認構造函數......我將其更改爲Activator.CreateInstance,並且它工作正常 – 2010-09-14 09:07:22
寫了我的問題後不久,我想出了'return Expression。 Lambda>(Expression.Convert(Expression.Default(type),typeof(object)))。Compile()();',但你的更好。 –
GiddyUpHorsey
2010-09-14 09:08:40
@Giddy:這將是一種非常昂貴的方式,因爲您在每次調用時都將表達式樹編譯爲IL(然後JIT將不得不將其編譯爲本機)。 – 2010-09-14 17:29:11
是的,我同意。這就是爲什麼我不使用它,而是使用madgnome的解決方案。雖然,這是更短,更易讀的代碼,而不是性能,這促使我使用他的。對於我的場景,性能不是太大。 – GiddyUpHorsey 2010-09-14 22:20:08