Использование некоторых расширений для упрощения работы с MemberInfo
:
// ***
// *** Type Extensions
// ***
public static List<MemberInfo> GetPropertiesOrFields(this Type t, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
t.GetMembers(bf).Where(mi => mi.MemberType == MemberTypes.Field | mi.MemberType == MemberTypes.Property).ToList();
// ***
// *** MemberInfo Extensions
// ***
public static object GetValue(this MemberInfo member, object srcObject) {
switch (member) {
case FieldInfo mfi:
return mfi.GetValue(srcObject);
case PropertyInfo mpi:
return mpi.GetValue(srcObject);
default:
throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
}
}
public static T GetValue<T>(this MemberInfo member, object srcObject) => (T)member.GetValue(srcObject);
public static void SetValue<T>(this MemberInfo member, object destObject, T value) {
switch (member) {
case FieldInfo mfi:
mfi.SetValue(destObject, value);
break;
case PropertyInfo mpi:
mpi.SetValue(destObject, value);
break;
default:
throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
}
}
Это расширение можно использовать для копирования соответствующих значений членов объекта в другой тип:
// Convert any object to another Type by copying over common properties or fields
public static T ToType<T>(this object obj) where T : new() {
var ansObj = new T();
var ansFields = typeof(T).GetPropertiesOrFields().ToDictionary(pf => pf.Name);
foreach (var prop in obj.GetType().GetPropertiesOrFields())
if (ansFields.TryGetValue(prop.Name, out var destpf))
destpf.SetValue(ansObj, prop.GetValue(obj));
return ansObj;
}
конечный результат будет:
var ans = sourceList.Select(m => m.ToType<Customer>()).ToList();
Но я думаю, что вам было бы намного лучше использовать интерфейсы и иметь общий базовый интерфейс:
interface IIDBase {
int Id { get; set; }
string Name { get; set; }
string PhoneNo { get; set; }
}
public class Customer {
public int Id { get; set; }
public string Name { get; set; }
public string PhoneNo { get; set; }
}
public class Products : IIDBase {
public int Id { get; set; }
public string Name { get; set; }
public string PhoneNo { get; set; }
// ...
}
Тогда вы просто приводите к List<IIDBase>
:
var ans = sourceList.Cast<IIDBase>().Select(m => new Customer {
Id = m.Id,
Name = m.Name,
PhoneNo = m.PhoneNo
});