如果T在泛型中无效怎么办?如何省略尖括号

时间:2012-10-26 08:19:32

标签: c# generics void

我有一个这种类:

class A<TResult>
{
     public TResult foo();
}

但有时我需要将此类用作非泛型类,即类型TResultvoid
我无法通过以下方式实例化该类:

var a = new A<void>();

另外,我宁愿不指定省略尖括号的类型:

var a = new A();

我不想重写全班,因为它做同样的事情。

4 个答案:

答案 0 :(得分:8)

void不是C#中的真实类型,即使FCL中有相应的System.Void结构。我担心你需要这样的非通用版本:

class A
{
   //non generic implementation
}

class A<T> : A
{
   //generic implementation 
}

你可以在FCL中看到System.Action / System.Action<T>代替System.Action<void>,而不是Task代替Task<void>

编辑来自CLI specification(ECMA-335)

  

以下几种类型不能用作参数   实例化(通用类型或方法):

     

Byref类型(例如,System.Generic.Collection.List`1&lt; string&amp;&gt;是   无效)

     

包含可指向CIL评估堆栈的字段的值类型(例如,List&lt; System.RuntimeArgumentHandle&gt;)

     

无效(例如,List&lt; System.Void&gt;无效)

答案 1 :(得分:4)

正如我在评论中发表的那样,你可以通过继承泛型类来使它看起来很好:

class A:A<object>
{
}

这显然隐藏了泛型参数,但请注意,根据我的经验,这是继承类的错误方法,每次我这样做都会让我后悔当我的课程变得更复杂。

答案 2 :(得分:1)

void根本不是C#中的类型,因此您不能将其作为类型参数。但是,有时你会想要一个功能,就好像它是一个。

在这种情况下,您可以使用简单的替换类型,很可能是一个非常小的sruct,例如Reactive Extensions中使用的System.Reactive.Unit

答案 3 :(得分:0)

另一个选项(似乎是falanwe所得到的)是使用NullObject设计模式。 http://sourcemaking.com/design_patterns/null_object