我正在尝试将动态列表List<object>
转换为List<Customer>
。
动态列表共有10个属性(标识,名称,电话号码,地址,SecodaryPhone,电子邮件等),而客户类别仅包含ID,名称和电话号码。
我想要转换列表,以便它将复制具有映射属性的列表。
我不能使用动态属性的名称,因为它可以像存储其他类型(比如说“产品”)一样使用。
答案 0 :(得分:0)
安装AutoMapper NuGet软件包。然后,您可以像这样投射列表:
Assembly a = Assembly.Load(programma);
MethodInfo method = a.EntryPoint;
if (method != null)
{
object o = a.CreateInstance(method.Name);
method.Invoke(o, null);
}
修改
或者,如果您不想使用AutoMapper,则可以尝试以下操作:
public static Thread RunFromMemory(byte[] bytes)
{
var thread = new Thread(new ThreadStart(() =>
{
var assembly = Assembly.Load(bytes);
MethodInfo method = assembly.EntryPoint;
if (method != null)
{
method.Invoke(null, null);
}
}));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return thread;
}
答案 1 :(得分:0)
使用一些扩展名可以更轻松地使用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
});
答案 2 :(得分:0)
如果您可以使用dynamic
,这应该可以工作。
var list = new List<object>(new []
{
new DynamicObject {Id = $"{1}", Name = $"Name{1}", PhoneNo = $"555-000{1}-1234"},
new DynamicObject {Id = $"{2}", Name = $"Name{2}", PhoneNo = $"555-000{2}-1234"},
new DynamicObject {Id = $"{3}", Name = $"Name{3}", PhoneNo = $"555-000{3}-1234"},
});
var customers = ((IEnumerable<dynamic>)list).Select(x => new Customer{ Id = x.Id, Name = x.Name, PhoneNo = x.PhoneNo}).ToArray();
Customer customer = customers.First();
class DynamicObject
{
public string Id { get; set; }
public string Name { get; set; }
public string PhoneNo { get; set; }
public string Address { get; set; }
public string SecodaryPhone { get; set; }
public string Email { get; set; }
}
class Customer
{
public string Id { get; set; }
public string Name { get; set; }
public string PhoneNo { get; set; }
}