如果项相等,则将项从一个类映射到另一个类

本文关键字:一个 映射 另一个 如果 | 更新日期: 2023-09-27 18:07:05

假设我有一个class看起来像这样:

public class Person
{
     public string Name {get; set;}
     public int Number {get; set;}
}

另一个看起来像这样:

public class Dog
{
     public string Name {get; set;}
     public int Number {get; set;}
}

它们是两个不同的类,但它们恰好具有完全相同的元素(字符串Name和整型Number)

是否有一个简单的方法在c#中,说,如果我有一个Person的实例,然后创建一个Dog的实例与相同的NameNumber ?

例如:

Person person = new Person();
person.Name = "George";
person.Number = 1;

我知道我不能简单地离开:

Dog dog = person;

因为它们是两种不同的类型。但是在c#中有没有一种方法来检查"哦,如果它们有相同的元素,设置Dog的相同元素等于Person的相同元素。"但是我觉得一定有比这样做更简单的方法:

dog.Name = person.Name;
dog.Number = person.Number;

特别是当类有很多元素时。另外,如果有人想知道,这两个不同的类在API的两个不同部分中,所以我也不能简单地将它们关联起来。

如果项相等,则将项从一个类映射到另一个类

您可以使用AutoMapper:

public Dog UsingAMR(Person prs)
{
    var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<Person, Dog>();
    });
    IMapper mapper = config.CreateMapper();
    return mapper.Map<Person, Dog>(prs);
}

那么你可以很容易地:

Person ps = new Person {Name = "John", Number = 25};
Dog dog = UsingAMR(ps);

只是不要忘记先从包管理器控制台安装AutoMapper,如参考中提到的:

  1. Tools菜单单击NuGet Package Manager ==> Package Manager Console
  2. 然后输入以下命令:

    PM> Install-Package AutoMapper
    

面向对象的方法。

public class Mammal
{
    public Mammal(Mammal toCopy)
    {
        Name = toCopy.Name;
        Number = toCopy.Number;
    }
    public string Name {get; set;}
    public int Number {get; set;}
}
public class Person: Mammal
{
    public Person(Mammal toCopy) {} /* will default to base constructor */
}
public class Dog: Mammal
{
    public Dog(Mammal toCopy) {} /* will default to base constructor */
}

允许以下操作:

Person person = new Person();
person.Name = "George";
person.Number = 1;
Dog dog = new Dog(person);

在项目中安装AutoMapper

作为一个最佳实践(对于web应用程序),你可以在你的App_Start文件夹中创建一个新的类(应该从Profile派生),它将包含你的项目的所有映射。

namespace MyApp.App_Start
{
    public class MyAppMapping : Profile
    {
        public MyAppMapping()
        {
            CreateMap<Person, Dog>();
            //You can also create a reverse mapping
            CreateMap<Dog, Person>();
            /*You can also map claculated value for your destination. 
            Example: you want to append "d-" before the value that will be
            mapped to Name property of the dog*/
            CreateMap<Person, Dog>()
            .ForMember(d => d.Days, 
             conf => conf.ResolveUsing(AppendDogName)); 
        }
        private static object AppendDogName(Person person)
        {
            return "d-" + person.Name;
        }
    }
}

然后在Global.asax

中的Application_Start方法中初始化您的映射
protected void Application_Start()
{
    Mapper.Initialize(m => m.AddProfile<MyAppMapping>());
}

您现在可以使用您已经创建的映射

var dog = AutoMapper.Mapper.Map<Person, Dog>(person);

如果你不使用大的泛型列表,你可以使用LinQ。

var persons = new List<Person>();
// populate data [...]
var dogs = persons.Select(p=>new Dog{Name=p.Name,Number=p.Number}).ToList();

这很容易记住,并且您可以预先过滤数据。