2015-07-14 3 views
0

У меня есть все виды классов, который представляет объекты, например:Возможно ли иметь общий метод с ограничением конструктора с параметром?

public class Person 
{ 
    public int PersonID { get; set; } 
    public string PersonName { get; set; } 
    public bool IsSystemManager { get; set; } 
    public bool IsSystemAdmin { get; set; } 

    public Person() { } 

    public Person(DataRow row) 
    { 
     PersonID = (int)row["person_id"]; 
     PersonName = row["person_name"] as string; 
     IsSystemManager = (bool)row["is_manager"]; 
     IsSystemAdmin = (bool)row["is_admin"]; 
    } 
} 

И я хочу, чтобы иметь расширение для DataTable, который превращает его в список объекта класса, как это:

public static List<T> ToObjectList<T>(this DataTable table) where T : new(DataRow dr) //this is a compilation error 
{ 
    List<T> lst = new List<T>(); 

    foreach (DataRow row in table.Rows) 
     lst.Add(new T(row)); 

    return lst; 
} 

Но у меня не может быть ограничения для конструктора с параметром DataRow.

Есть ли способ иметь такой способ расширения?

+0

@ haim770 он возвращает 'List ' а не 'List 'и T предполагается, что в конструкторе DAtaRow в конструкторе –

+1

проблема будет отложена, я бы настоятельно рекомендовал не передавать datarow в ctor, а взрывать требуемые параметры (имея по одному для каждого члена ct или наборы), вы можете передать datarow, который заставляет вызов ctor сбой легко – nozzleman

ответ

4

Нет, вы не можете требовать конструктор с параметрами. О лучшем случае вы можете сделать здесь будет требовать лямбда:

public static List<T> ToObjectList<T>(this DataTable table,Func<DataRow,T> convert) 
{ 
    List<T> lst = new List<T>(); 

    foreach (DataRow row in table.Rows) 
     lst.Add(convert(row)); 

    return lst; 
} 

Использование:

var list = myDataTable.ToObjectList(dr=>new Person(dr)); 

Дальнейшее чтение:

Constraints on type parameters

+0

Очень приятно, спасибо вам большое :) –

0

Вы не можете указать тип ограничение для общих типов. Что вы можете сделать, однако, заключается в создании двух различных ограничений следующим образом:

public static List<T> ToObjectList<T>(this DataTable table) where T : DataRow where T : new() 

Здесь вы указать, что параметр T должен быть типа DataTable (или производный из DataTable) и новый экземпляр этого л быть созданный внутри вашего метода

+0

Насколько я понимаю, он не хочет возвращать 'List ' but 'List '. – nozzleman

+0

TS хотел добавить ограничение, которое DataRow должно быть принято как параметр конструктора new (Datarow), и я просто указал, что это невозможно. – Fabjan

0

Нет, вы можете только требуется пустой конструктор с общим концом straints.

Альтернативный шаблон будет требовать Load метод:

public interface ILoadable 
{ 
    void Load(DataRow row); 
} 

public class Person : ILoadable 
{ 
    ... 

    public Person() { } 

    public void Load(DataRow row) 
    { 
     PersonID = (int)row["person_id"]; 
     ... 
    } 
} 

Тогда вы можете объявить свой метод следующим образом:

public static List<T> ToObjectList<T>(this DataTable table) where T : ILoadable, new()