C# 如何映射两个不同对象的属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17675408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to map properties of two different objects?
提问by Murugavel
I want to know how to map fields of two different objects and assign the values to it.
我想知道如何映射两个不同对象的字段并为其分配值。
Eample:
示例:
public class employee
{
public int ID { get; set; }
public string Name { get; set; }
}
public class manager
{
public int MgrId { get; set; }
public string MgrName { get; set; }
}
Now I have a List object. I want to assign the values to "manager" class. Any automatic way to do that. I can do it explicitly and assigning values to it. But my object is very huge thats the problem. I dont want to use any third party tools too.
现在我有一个 List 对象。我想将值分配给“经理”类。任何自动方式来做到这一点。我可以明确地做到这一点并为其分配值。但我的对象非常大,这就是问题所在。我也不想使用任何第三方工具。
Note: It can't have any prefix for manager. It can be anything. (Ex: mgrId can be like mgrCode)
注意: manager 不能有任何前缀。它可以是任何东西。(例如:mgrId 可以像 mgrCode)
采纳答案by Alex Filipovici
You could use reflection for it, even by ignoring the property casing (notice the employee.ID
vs. manager.MgrId
):
您可以使用反射,即使忽略属性大小写(注意employee.ID
vs. manager.MgrId
):
class Program
{
static void Main(string[] args)
{
var employee = new Employee() { ID = 1, Name = "John" };
var manager = new Manager();
foreach (PropertyInfo propertyInfo in typeof(Employee).GetProperties())
{
typeof(Manager)
.GetProperty("Mgr" + propertyInfo.Name,
BindingFlags.IgnoreCase |
BindingFlags.Instance |
BindingFlags.Public)
.SetValue(manager,
propertyInfo.GetValue(employee));
}
}
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Manager
{
public int MgrId { get; set; }
public string MgrName { get; set; }
}
If you don't know the Mgr
prefix, you could only match by suffixes:
如果您不知道Mgr
前缀,则只能按后缀匹配:
foreach (PropertyInfo propertyInfo in typeof(Employee).GetProperties())
{
typeof(Manager).GetMembers()
.OfType<PropertyInfo>()
.FirstOrDefault(p => p.Name.EndsWith(propertyInfo.Name,
StringComparison.CurrentCultureIgnoreCase))
.SetValue(manager,
propertyInfo.GetValue(employee));
}
And a very narrow and impractical assumption: mapping based on the property order (if you are expecting the 2 types to have properties defined in the same sequence and number, the only difference being the property names). I wouldn't recommend anyone using it in real life, but still, here it is (just to make it more fragile:) ):
还有一个非常狭隘且不切实际的假设:基于属性顺序的映射(如果您希望这 2 种类型的属性定义在相同的序列和编号中,唯一的区别是属性名称)。我不会推荐任何人在现实生活中使用它,但它仍然存在(只是为了让它更脆弱:)):
typeof(Employee)
.GetProperties()
.Select((p, index) =>
new { Index = index, PropertyInfo = p })
.ToList()
.ForEach(p =>
{
typeof(Manager)
.GetProperties()
.Skip(p.Index)
.FirstOrDefault()
.SetValue(manager,
p.PropertyInfo.GetValue(employee));
});
回答by Dustin Kingen
Use reflection or AutoMapper. I recommend the latter since writing new code is wasteful if it doesn't have a purpose.
使用反射或AutoMapper。我推荐后者,因为如果没有目的,编写新代码就是浪费。
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Manager
{
public int MgrId { get; set; }
public string MgrName { get; set; }
}
Mapper.Initialize(cfg =>
{
cfg.RecognizeDestinationPrefixes("Mgr");
cfg.CreateMap<Employee, Manager>();
});
var manager = Mapper.Map<Employee, Manager>(new Employee { Id = 1, Name = "Fred" });
Console.WriteLine("Id: {0}", manager.MgrId);
Console.WriteLine("Name: {0}", manager.MgrName);
If the properties don't have an idiomatic source identifier then use AutoMapper's projection.
如果属性没有惯用的源标识符,则使用 AutoMapper 的投影。
Mapper.CreateMap<Employee, Manager>()
.ForMember(dest => dest.MgrCode, opt => opt.MapFrom(src => src.ID))
.ForMember(dest => dest.MgrName, opt => opt.MapFrom(src => src.Name))