Мне нравится подход MikeEast, но мне не нравится идея, что вы должны передавать сопоставление каждому вызову GetList
. Попробуйте вместо этого вариант:
public static class DataSetEx
{
private static Dictionary<Type, System.Delegate> __maps
= new Dictionary<Type, System.Delegate>();
public static void RegisterMap<T>(this Func<DataRow, T> map)
{
__maps.Add(typeof(T), map);
}
public static IEnumerable<T> GetList<T>(this DataSet dataSet)
{
var map = (Func<DataRow, T>)(__maps[typeof(T)]);
return dataSet.Tables[0].AsEnumerable().Select(map);
}
}
Теперь, учитывая классы Apple
& Orange
, вызовите следующие методы для регистрации карт:
DataSetEx.RegisterMap<Apple>(r => new Apple()
{
Color = r[0].ToString(),
Year = r[1].ToString(),
Brand= r[2].ToString(),
});
DataSetEx.RegisterMap<Orange>(r => new Orange()
{
Variety = r[0].ToString(),
Location = r[1].ToString(),
});
Тогда вы можете просто позвонить GetList
без карты, например:
var ds = new DataSet();
// load ds here...
// then
var apples = ds.GetList<Apple>();
// or
var oranges = ds.GetList<Orange>();
Это дает хорошее разделение кода без необходимости размышления или повторения.
Это также не мешает вам использовать гибридный подход с использованием отражения в случаях, когда карта явно не была определена. Вы как бы можете получить лучшее из обоих миров.