7

我有一个这种类型的类:

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

但有时我需要把这个类当作一个非泛型类来使用,即类型TResultvoid.
我无法通过以下方式实例化该类:

var a = new A<void>();

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

var a = new A();

我不想重写整个课程,因为它做同样的事情。

4

4 回答 4

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 规范(ECMA-335)编辑

以下类型的类型不能用作(泛型类型或方法的)实例化中的参数:

Byref 类型(例如,System.Generic.Collection.List`1<string&> 无效)

包含可以指向 CIL 评估堆栈的字段的值类型(例如,List<System.RuntimeArgumentHandle>)

void(例如,List<System.Void> 无效)

于 2012-10-26T08:23:30.820 回答
4

正如我在评论中发布的那样,您可以通过从泛型类继承来使其看起来不错:

class A:A<object>
{
}

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

于 2012-10-26T08:34:51.910 回答
1

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

In this kind of case, you may make use of a simple replacement type, most likely a very small sruct, such as System.Reactive.Unit used in Reactive Extensions.

于 2012-10-26T08:36:00.387 回答
0

Another Option (which seems to be what falanwe was getting at) is to use the NullObject Design Pattern. http://sourcemaking.com/design_patterns/null_object

于 2014-06-03T15:43:08.657 回答