这是一个学术问题比什么都重要......我知道有更多实用的手段可以开发......
假设您有以下代码:
public MyObject1 AssignTest(MyObject1 obj1,MyObject2 obj2){
Run Code Online (Sandbox Code Playgroud)public MyObject1 AssignTest (MyObject1 obj1, MyObject2 obj2) { //Code here for auto map }
MyObject1和MyObject2具有完全相同的可用属性.是否可以自动将MyObject1中指定的所有值分配给MyObject2?而不是通过声明性地分配值(即MyObject1.Property1 = MyObject2.Property1等)
映射库(如ValueInjector或AutoMapper)对于这种功能非常有用.
使用AutoMapper,您可以使用类似的东西创建映射
Mapper.CreateMap<MyObject1,MyObject2>();
Run Code Online (Sandbox Code Playgroud)
它有许多默认约定,其中一个默认约定,它将复制具有相同类型/名称的属性.
然后实际做这样的映射
var myObject2 = Mapper.Map<MyObject1,MyObject2>(myObject1);
Run Code Online (Sandbox Code Playgroud)
当然,你也可以通过反射很容易地做到这一点,但是对于像这样的库,有人已经花了很多心思添加各种方便的映射功能,以及完成性能调整.例如,AutoMapper使用IL生成来读取值而不是反射,因此重复映射事物的速度要快得多(非常适合映射大量事物)
实现这一目标的一种可能性(例如,为了创建自己的自动化程序或理解它基本上如何工作)将使用(如已经建议的)反射.代码可能如下所示:
// TODO: error handling
// Test classes
public class A
{
public string Name { get; set; }
public int Count;
}
public class B
{
public string Name { get; set; }
public int Count;
}
// copy routine
public B CopyAToB(A a)
{
B b = new B();
// copy fields
var typeOfA = a.GetType();
var typeOfB = b.GetType();
foreach (var fieldOfA in typeOfA.GetFields())
{
var fieldOfB = typeOfB.GetField(fieldOfA.Name);
fieldOfB.SetValue(b, fieldOfA.GetValue(a));
}
// copy properties
foreach (var propertyOfA in typeOfA.GetProperties())
{
var propertyOfB = typeOfB.GetProperty(propertyOfA.Name);
propertyOfB.SetValue(b, propertyOfA.GetValue(a));
}
return b;
}
Run Code Online (Sandbox Code Playgroud)
该功能可以这样使用:
var a = new A
{
Name = "a",
Count = 1
};
var b = CopyAToB(a);
Console.Out.WriteLine(string.Format("{0} - {1}", b.Name, b.Count));
Run Code Online (Sandbox Code Playgroud)
输出是:
a - 1
Run Code Online (Sandbox Code Playgroud)
请注意,反射的使用需要付出代价 - 它会降低性能.使用反射,您可以访问私有和公共对象成员.例如,这可以从Visual Studio中使用,以创建测试访问器对象,以便访问所有测试对象成员.
请查看现有的自动化程序(请参阅链接的其他答案)并使用它们而不是自己重新发明轮子 - 现有的库已针对速度进行了优化,经过全面测试并且使用起来非常舒适.这样您就可以最大限度地减少代码中的错误.