创建泛型类型实例的方法

时间:2014-10-27 22:00:03

标签: c# generics

我正在尝试创建一个泛型方法。我希望调用者能够定义两种不同的类型。

private TableRow AddRowHelper<TROW, TCELL>(params string[] content) where TROW : TableRow where TCELL : TableCell
{
    TableRow row = new TROW();
    foreach (var text in content)
    {
        TableCell cell = new TCELL();
        cell.Text = text;
        row.Cells.Add(cell);
    }
    productsTable.Rows.Add(row);
    return row;
}

上面的代码给我一个错误。

  

错误4无法创建变量类型'TROW'的实例,因为它没有new()约束“

是否可以指定new和基本类型约束?当我指定类型必须来自TableRow时,为什么我需要一个新的约束,new总是有一个{{1}}运算符。

3 个答案:

答案 0 :(得分:5)

  

当我指定类型必须从TableRow派生时,为什么我需要一个新的约束,TableRow总是有一个新的运算符。

TROW可能是一个继承自TableRow并且没有默认公共构造函数的类型。这就是为什么需要添加new()约束。

答案 1 :(得分:3)

默认的无参数构造函数可以由派生类隐藏。因此,new()约束不能从基类继承。

样品:

public class TableRow
{ } // implements a default, parameterless constructor

public class DeivedRow : TableRow
{
    public DerivedRow(string s)
    { } // no parameterless constructor
}

答案 2 :(得分:1)

可以指定new和base-type约束。这样做会使您的方法签名看起来像这样

public TableRow AddRowHelper<TROW, TCELL>(params string[] content) 
       where TROW : TableRow, new() where TCELL : TableCell, new()
{

每当基于泛型类型进行实例化时,必须使用new约束将泛型类型限制为具有公共无参数构造函数的类型。此外,在创建变量类型的实例时,方法不能提供参数。

你需要new约束,即使你已经指定类型必须派生自TableRow(它总是有一个新的运算符),因为派生类型可能没有公共无参数构造函数,那就是那个会被称为。

考虑一下:

public class A : TableRow
{
    private A(){}
}

并考虑使用它

AddRowHelper<A,TableCell>(args);

这将导致编译错误,

  

&#39; A&#39;必须是具有公共无参数构造函数的非抽象类型才能将其用作参数&#39; TROW&#39;通用类型或方法&#39; AddRowHelper(params string [])&#39;