C#泛型:约束T,其中T:Object不编译;错误:约束不能是特殊类'对象'

时间:2012-05-17 23:12:01

标签: c# .net generics object clr

当我使用以下对象约束T时:

public interface IDoWork<T> where T : Object
{
    T DoWork();
}

我收到错误:

  

约束不能是特殊类'对象'

这是否意味着下面的编译存在隐含的差异?

public interface IDoWork<T> // where T : Object
{
    T DoWork();
}

3 个答案:

答案 0 :(得分:49)

如果要将泛型类型约束为引用类型,请使用: class

public interface IDoWork<T> where T : class
{
    T DoWork();
}

这将禁止泛型类型成为值类型,例如int或结构。

答案 1 :(得分:15)

两个约束之间没有区别,除了不允许明确说明无用之外。

C#4.0语言规范(10.1.5类型参数约束)说明了两件事:

  

该类型不能是对象。因为所有类型都来自对象,   如果允许,这样的约束就没有效果。

     

...

     

如果T没有主要约束或类型参数约束,则为   有效的基类是对象。

在您的评论中,您说您试图使T属于Void类型。 Void是一种特殊类型,表示没有返回类型,不能用于代替T,这需要适当的具体类型。如果需要,您必须创建方法的void版本和T版本。

答案 2 :(得分:0)

根据C#4.0语言规范(编码:[10.1.5]类型参数约束)说明两件事:

  

1]类型不能是对象。因为所有类型都来自对象,   如果允许,这样的约束就没有效果。

     

2]如果T没有主要约束或类型参数约束,则其有效   基类是对象。

定义泛型类时,可以对实例化类时客户端代码可用于类型参数的类型类型应用限制。如果客户端代码尝试使用约束不允许的类型来实例化您的类,则结果是编译时错误。这些限制称为约束。使用where contextual关键字指定约束。 如果要将泛型类型约束为引用类型,请使用:class。

根据MSDN

约束不能是特殊类'标识符'。以下类型不能用作约束:

  • System.Object的
  • 的System.Array
  • System.Delegate
  • System.Enum
  • System.ValueType。