2011-05-18 39 views
2

我有這樣的事情如何創建一個可以初始化值變量爲0或引用變量來新(NOT NULL)

V Func<V>() 
{ 
    // do stuff 
    V res = default(V); 
// more stuff 
    return res; 
} 

的問題是,我想水庫是0或一個新的通用方法V

的實例

我嘗試創建2種方法

Func<V> where T: new() 
Func<V> where T: struct 

但令人驚訝的,這是不允許

我的解決辦法是有2個功能

FuncNew<V> where T: new() 
... 
res = new V(); 
.... 

FuncDefault<V> where T: struct 
... 
res = default(V) 
... 

編輯:總結答案

新(T)將新建立一個ref或值類型;我沒有意識到

+1

什麼是確定返回值是否是'V'或0的新實例? – Oded 2011-05-18 20:28:08

+0

你甚至沒有寫出正確的方法聲明,而'where T:new'的約束是無效的。即使它*有效,您也不能通過類型約束來重載方法。 – 2011-05-18 20:28:20

+4

在您嘗試的解決方案中,[約束不是簽名的一部分](http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the- signature.aspx)。 – 2011-05-18 20:28:40

回答

6

可以使用new()約束:

private V Func<V>() where V : new() 
{ 
    // do stuff 
    V res = new V(); 
// more stuff 
    return res; 
} 

值類型會被初始化爲全零,任何引用類型將使用他們的無參數的默認構造函數初始化。

如果引用類型沒有無參數的構造函數,它不能用於這個方法,你必須使用其他方法(SO上的其他地方有很多解決這個問題的方法,例如Passing arguments to C# generic new() of templated type

+1

注意,對於任何結構(包括'Nullable '),'new T()'等價於'default(T)'。 – 2011-05-18 20:27:44

+0

這不適用於值類型 – pm100 2011-05-18 20:48:37

+0

return V;有點魚腥味:) – 2011-05-18 20:49:15

0

所以你想結果對象是整數零,或者你的泛型類型的新實例?這是不可能的,因爲泛型類型參數只對整數類型有效,除非你指定object作爲返回類型。

public object Func<T>() 
    where T: new() 
{ 
    if(something) 
     return 0; 

    return new T(); 
} 

如果您正在嘗試製作默認初始化程序,則只需要新建該類型即可。這應該適用於整數類型和參考類型。

public T Func<T>() 
{ 
    return Activator.CreateInstance<T>(); 
} 
+0

一般來說,最好直接使用'new T()'而不是'Activator.CreateInstance ',因爲C#編譯器會插入一些優化以使其非常快速值類型。 – thecoop 2011-05-18 20:37:15

+0

確實。看過你的實現後,'new()'更簡潔。 – Tejs 2011-05-18 20:38:45

+0

我需要測試的'東西'是V是ref還是值類型 – pm100 2011-05-18 20:49:23