通用方法将新T添加到T列表中

时间:2015-02-05 22:00:14

标签: c# generics generic-constraints

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

   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'类型

我想做的是什么?我觉得必须是因为编译器不应该关心它是什么类型的列表 - 它只需要调用public,无参数构造函数并将新实例添加到传入的现有列表中。

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

  

类型T' must be convertible to BayClass'以便使用它   作为泛型类型或方法中的参数“T”

非常感谢任何指针。

2 个答案:

答案 0 :(得分:5)

投诉不是关于列表,而是关于T。如果您有ObservedList<MyClass>并将其传递给SetBayNumb(),则MyClass必须实施IBaySpec,并且必须具有无参数构造函数:public MyClass() { ... }。为什么?因为那是where T : IBaySpec, new()所说的。如果您删除where子句,则错误将消失,但您将无法再说new T()

答案 1 :(得分:3)

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

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

问题来自于T中对Method没有限制,因此编译器无法匹配SetBayNumb的参数。

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

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

给出了更好的错误:

  

类型&#39; TArg&#39;必须有一个公共无参数构造函数才能将其用作参数&#39; T&#39;在通用类型或方法中

请注意,错误中涉及两种不同的类型(当两者都称为相同时很难看到&#34; T&#34;)。

修正:

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