我有一類這個類型的:如果T在泛型中無效,該怎麼辦?如何省略尖括號
class A<TResult>
{
public TResult foo();
}
但有時我需要使用這個類作爲非通用類,即類型TResult
是void
。
我不能實例化類的方式如下:
var a = new A<void>();
另外,我寧願不指定類型省略尖括號:
var a = new A();
我不想再寫全班,因爲它做同樣的事情。
我有一類這個類型的:如果T在泛型中無效,該怎麼辦?如何省略尖括號
class A<TResult>
{
public TResult foo();
}
但有時我需要使用這個類作爲非通用類,即類型TResult
是void
。
我不能實例化類的方式如下:
var a = new A<void>();
另外,我寧願不指定類型省略尖括號:
var a = new A();
我不想再寫全班,因爲它做同樣的事情。
void
在C#中不是真正的類型,即使在FCL中有相應的System.Void
結構。我怕你在這裏需要一個非一般的版本是這樣的:
class A
{
//non generic implementation
}
class A<T> : A
{
//generic implementation
}
你可以看到整箱有System.Action
/System.Action<T>
,而不是System.Action<void>
,以及Task
而不是Task<void>
。
EDIT從CLI specification(ECMA-335):
以下種類型的不能用作 實例參數(通用類型或方法的):
的ByRef類型(例如,System.Generic。 Collection.List`1 < string &> is invalid)
包含可指向t的字段的值類型他CIL評估堆棧(例如,列表< System.RuntimeArgumentHandle>)
無效(例如,列表< System.Void>無效)
正如我張貼在評論,你可以使它看起來好通過繼承從通用類:
class A:A<object>
{
}
這顯然隱藏泛型參數,但要知道,在我的經驗,這是我每次做這個,我後悔了,而我的課有更復雜的時間出現在錯誤的方式來繼承類和。
相反,我可以重複使用數百行代碼的類,只需添加幾個這個技巧+1 – Nick
void不是C#中的一種類型,因此您不能將其作爲類型參數。但是,有時候你想要一個功能性就好像它是一個。
在這種情況下,您可以使用簡單的替換類型,很可能是非常小的sruct,例如Reactive Extensions中使用的System.Reactive.Unit。
另一種選擇(這似乎是法蘭威正在得到的)是使用NullObject設計模式。 http://sourcemaking.com/design_patterns/null_object
難道你不能只使用'object'嗎? – Davio
@達維奧是的,但它是可怕的... – Nick
在這種情況下,您必須創建一個沒有約束的單獨的類「A」。但是如果沒有T,類實現是怎樣的呢?你有一個'T foo()'方法。如果無效,T應該怎麼辦? – nawfal