2015-06-24 6 views
0

У меня есть следующая реализация, которая работает для преобразования строк в DataTable в List<T>. Интерфейс IDataItem просто содержит метод SetData, который принимает один объект DataRow.Преобразование DataRow в одно ограничение типа объекта

public class GroupedData<T> : List<T> where T : IDataItem, new() 
    { 
     public GroupedData(DataTable table) 
     { 
      for (int i = 0; i < table.Rows.Count; i++) 
      { 
       DataRow row = table.Rows[i]; 
       var newItem = new T(); 
       newItem.SetData(row); 
       Add(newItem); 
      } 
     } 
    } 

Этих свойства в классе я пытаюсь присвоить значение:

public class Details 
    { 
    public List<AuditData> AuditEntries { get; set; } 

    public AuditMethodSummaryData AuditMethodSummaryData { get; set; } 
    } 

С классом GroupedData, я могу выполнить следующие действия для заполнения AuditEntries:

var returnData = new Details(); 
returnData.AuditEntries = new GroupedData<AuditData>(dataSet.Tables[TableNames.AuditDetails]); 

Для второго свойства - AuditMethodSummaryData. Мне нужно назначить один объект вместо списка. Я не могу понять, как создать другой класс, который может выполнять функцию.

Примечание. Мне все равно нужно передать в DataTable. Однако таблица данных будет содержать только одну строку (из-за того, как работает система).

Единственное решение, с которым я столкнулся, приведен ниже. Я просто хочу, чтобы увидеть, если есть лучшее решение:

public class SingleData 
    { 
    public static T GetItem<T>(DataTable table) where T : IDataItem, new() 
    { 
     if (table.Rows.Count >= 1) 
     { 
     DataRow row = table.Rows[0]; 
     var newItem = new T(); 
     newItem.SetData(row); 
     } 
    } 
    } 

Что мне не нравится то, что я переместил ограничение от класса к методу. Есть ли способ сохранить его в классе? Избегание статического метода.

+2

Что проблема с созданием метода родовой вместо класса? Я могу только увидеть преимущества, действительно ... – Luaan

+0

@ Luaan Это справедливая точка. Это то, что я застрял в производственном коде. Благодарю. – JBond

ответ

1

Ну, для одного элемента вам не нужны дженерики вообще:

public class SingleItem : IDataItem 
{ 
    public SingleItem(DataTable table) 
    { 
    if (table.Rows.Count >= 1) 
    { 
     var row = table.Rows[0]; 
     SetData(row); 
    } 
    else 
    { 
     throw new ArgumentException("No rows.", "table"); 
    } 
    } 

    public abstract void SetData(DataRow row); 
} 

public AuditMethodSummaryData : SingleItem 
{ 
    public AuditMethodSummaryData(DataTable table) : base(table) 
    {} 
    public override void SetData(DataRow row) { /*...*/ } 
} 

Это еще не решает случай, когда вам нужно возвратить null для нулевых строк. В этом случае вы должны использовать фабричный шаблон, который может быть реализован по-разному - статический метод является легким, и я считаю приемлемым подход для вашего дела; если вы не хотите иметь статический метод, вы должны создать класс фабрики вместо нравится:

public class DataItemFactory<T> where T : IDataItem, new() 
{ 
    private readonly DataTable m_Table; 

    public DataItemFactory(DataTable table) 
    { 
    m_Table = table; 
    } 

    public T Create() 
    { 
    T result = default(T); 
    if (m_Table.Rows.Count > 1) 
    { 
     result = new T(); 
     result.SetData(m_Table.Rows[0]); 
    } 
    return result; 
    } 
} 

С использованием как:

returnData.AuditMethodSummaryData = 
    new DataItemFactory<AuditMethodSummaryData>(table).Create(); 
Смежные вопросы