2014-10-27 2 views
1

Я пытаюсь создать метод 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 и базовый тип ограничения? И почему мне нужно новое ограничение, когда я указал, что тип должен быть производным от TableRow, который всегда имеет new оператора.

+2

Представьте себе тип, похожий на открытый класс ChildOfTrow: TROW {private ChildOfTrow() {}} –

+0

Что вы подразумеваете под «TableRow всегда есть« новый »оператор? – haim770

+1

Да, * Можно указать как новое, так и базовое ограничение: 'где TROW: TableRow, new()'. – haim770

ответ

1

Можно указать как новый и базовый тип ограничения. Делать это сделает ваш метод подписи выглядеть следующим образом

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); 

Это вызовет ошибку компиляции,

'A' должен быть не абстрактный тип с открытый конструктор без параметров, чтобы использовать его в качестве параметра «TROW» в родовом типе или методе «AddRowHelper (params string [])»

5

почему мне нужно новое ограничение, когда я указал, что тип должен быть производным от TableRow, w у которого всегда есть новый оператор.

Ну TROW может быть типом, который наследует от TableRow и не имеет по умолчанию общественного constructor.That поэтому вам нужно добавить new() ограничение а.

3

По умолчанию конструктор без параметров может быть скрыт производящим классом. Следовательно, ограничение new() не может быть унаследовано от базового класса.

Пример:

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

public class DeivedRow : TableRow 
{ 
    public DerivedRow(string s) 
    { } // no parameterless constructor 
} 
Смежные вопросы