Copy object field by field
I have defined a class1 which is inherited from base 1. I have also defined another class2 which contains simila members as in class1 but this class inherited from base2.
How can I convert class1 to Class2?
One options is I have to assign one property at a time like
Class2.a = Class1.a;
Class2.b = Class1.b;
Class2.c = Class1.c;
Is there any better alternative in .NET开发者_运维知识库?
You can write your own extension method, like bellow:
public static class ExtendedClassPropMapping
{
public static Y MapTo<T, Y>(this T input) where Y : class, new()
{
Y output = new Y();
var propsT = typeof(T).GetProperties();
var propsY = typeof(Y).GetProperties();
var similarsT = propsT.Where(x =>
propsY.Any(y => y.Name == x.Name
&& y.PropertyType == x.PropertyType)).OrderBy(x=>x.Name).ToList();
var similarsY = propsY.Where(x=>
propsT.Any(y=>y.Name == x.Name
&& y.PropertyType == x.PropertyType)).OrderBy(x=>x.Name).ToList();
for (int i=0;i<similarsY.Count;i++)
{
similarsY[i]
.SetValue(output, similarsT[i].GetValue(input, null), null);
}
return output;
}
}
and use it like:
var test = firstObject.MapTo<class1, class2>();
if you have to do it between a lot of different types you could consider using AutoMapper
Your current solution is perfectly acceptable and is a very explicit way of mapping object A to object B.
Most mapping libraries like AutoMapper allow convention based mapping. If property names and types align, it will map for you with little to no configuration required. Depending on how similar the target objects are, this approach might still require you to do some work. The downside is that it's not as explicit and depending on the amount of manual configuration you need to do, you might just be adding complexity.
I am just piggy-backing from Saeed, but this is a tiny bit easier to use and read:
public static class ExtendedClassPropMapping
{
public static Y MapTo<Y>(this object input) where Y : class, new()
{
Y output = new Y();
var propsT = input.GetType().GetProperties();
var propsY = typeof(Y).GetProperties();
var similarsT = propsT.Where(x =>
propsY.Any(y => y.Name == x.Name
&& y.PropertyType == x.PropertyType)).OrderBy(x => x.Name).ToList();
var similarsY = propsY.Where(x =>
propsT.Any(y => y.Name == x.Name
&& y.PropertyType == x.PropertyType)).OrderBy(x => x.Name).ToList();
for (int i = 0; i < similarsY.Count; i++)
{
similarsY[i]
.SetValue(output, similarsT[i].GetValue(input, null), null);
}
return output;
}
public static T MapNew<T>(this T input) where T : class, new()
{
T output = new T();
var similarsT = input.GetType().GetProperties().OrderBy(x => x.Name).ToList();
var similarsY = output.GetType().GetProperties().OrderBy(x => x.Name).ToList();
for (int i = 0; i < similarsY.Count; i++)
{
similarsY[i]
.SetValue(output, similarsT[i].GetValue(input, null), null);
}
return output;
}
}
Then you can use them like so:
public Teacher ConvertInterfaceToClass(ITeacher teacher)
{
return teacher.MapTo<Teacher>();
}
public void CopyTeacher(Teacher source, out Teacher destination)
{
destination = source.MapTo<Teacher>();
}
精彩评论