-3

我正在尝试将通用列表传递给将向列表添加新项目的函数。我有以下精简示例:

   private void SetBayNumb<T>(ObservedList<T> bayList) where T : IBaySpec, new()
   {
     var bay = new T();
     bayList.Add(bay);
   }

调用它的方法有这个错误:

T' must have a public parameterless constructor in order to use it as parameter泛型类型或方法中的类型T'

我正在尝试做的事情可能吗?我觉得它一定是因为编译器不应该关心它是什么类型的列表 - 它只需要调用公共的无参数构造函数并将新实例添加到传入的现有列表中。

我猜问题是接口不能保证它的实现者会有一个公共构造函数,但即使我给它一个具体的类,我也会得到这个错误:

类型T' must be convertible toBayClass' 以便在泛型类型或方法中将其用作参数“T”

将非常感谢任何指针。

4

2 回答 2

5

投诉不是关于清单,而是关于T。如果你有一个ObservedList<MyClass>并将它传递给SetBayNumb(),MyClass必须实现IBaySpec并且它必须有一个无参数的构造函数: public MyClass() { ... }. 为什么?因为就是这么where T : IBaySpec, new()说的。如果您删除该where子句,错误将消失,但您将不再能够说new T().

于 2015-02-05T22:02:18.750 回答
3

我认为您的调用代码看起来像

 void Method<T>(ObservedList<T> bayList)
 {
    SetBayNumb<T>(bayList);
 }

问题来自对Tin没有限制的事实Method,因此编译器无法匹配SetBayNumb.

请注意,泛型类型名称只是名称 - 您可以选择任何您喜欢的名称,它可以帮助推理错误。使用不同命名的泛型参数重写相同的方法,例如:

 void Method<TArg>(ObservedList<TArg> bayList)
 {
    SetBayNumb<TArg>(bayList);
 }

给出更好的错误:

类型“TArg”必须具有公共无参数构造函数,以便在泛型类型或方法中将其用作参数“T”

请注意,错误涉及两种不同的类型(当两者都称为相同的“T”时很难看出)。

修复:

  • 对外部泛型方法指定相同的限制(Method<TArg>(ObservedList<TArg> bayList) where TArg : ... new() )
  • 指定T在通用类级别而不是单个方法上
  • 传递满足这两个要求的具体类(列表中项目的类应实现接口并具有无参数构造函数)。
于 2015-02-05T22:40:09.813 回答