【问题标题】:Copy from one list of objects to another with the same structure从一个对象列表复制到具有相同结构的另一个对象列表
【发布时间】:2019-03-26 12:06:56
【问题描述】:

如何将一个对象列表中的所有内容复制到另一个对象列表中。两个对象的结构相同,但名称不同。

代码如下:

 class Program
{
    static void Main(string[] args)
    {
        List<Test> lstTest = new List<Test>();
        List<Test2> lstTest2 = new List<Test2>();

        lstTest.Add(new Test { Name = "j", Score = 2 });
        lstTest.Add(new Test { Name = "p", Score = 3 });

        lstTest2 = lstTest.ConvertAll(x => (Test)x);

    }
}

class Test
{
    private string name;
    private int score;

    public string Name
    {
        get { return name;  }
        set { this.name = value; }
    }

    public int Score
    {
        get { return score; }
        set { this.score = value; }
    }
}

class Test2
{
    private string name;
    private int score;

    public string Name
    {
        get { return name; }
        set { this.name = value; }
    }

    public int Score
    {
        get { return score; }
        set { this.score = value; }
    }
}

我得到的错误是

不能隐式转换类型System.Collections.Generic.List&lt;Test&gt;System.Collections.Generic.List&lt;cTest2&gt;

【问题讨论】:

  • Automapper 是很好的解决方案,但我不允许使用它:(
  • 这两个类是相同的,在现实世界的场景中,一个通用的基类或接口将是最好的方法,imo
  • @Josef 没有魔术棒,您要么手动完成,要么使用一些自动映射工具完成。并且根据您当前提供的示例,它应该很容易,但是如果您说您有复杂的东西并且无法使用它,那么您对解决方案的期望是什么?

标签: c# generic-list


【解决方案1】:

如果您不想使用 automapper 或其他映射工具,可以使用 select 和 new instance 执行此操作,然后返回一个列表:

lstTest2 = lstTest.Select(e => new Test2()
{
    Score = e.Score,
    Name = e.Name
}).ToList();

如果是 Automapper,您可以执行以下操作:

var config = new MapperConfiguration(cfg => {

    cfg.CreateMap<Test, Test2>();
});
IMapper iMapper = config.CreateMapper();
lstTest2 = iMapper.Map<List<Test>, List<Test2>>(lstTest);

在配置中定义类型转换。将它从一种类型映射到另一种类型。

您当然可以扩展您的实现以使其具有通用性。

文档参考:

【讨论】:

  • 这似乎是一个不错的解决方案,但是如果我有更多的对象,对象内部的变量怎么办?
  • 因此 Automapper 或 expressmapper 是帮助处理复杂事物的其他解决方案之一。如果您愿意,我可以为此示例提供 automapper 或 expressmapper 示例
【解决方案2】:

您正在尝试将 Test 隐式转换为 Test2 对象。更正代码的一种简单方法是构造 Test2 对象:

lstTest2 = lstTest.ConvertAll(x => new Test2 { Name = x.Name, Score = x.Score });

即使底层结构相同,也不能从Test 转换为Test2。如果要显式转换,则必须定义转换运算符:

class Test2 {
    // all code of class Test2

    public static explicit operator Test2(Test v)
    {
        return new Test2 { Name = v.Name, Score = v.Score };
    }
}

那你就可以投ConvertAll:

lstTest2 = lstTest.ConvertAll(x => (Test2)x);

【讨论】:

  • 这是一个很好的解决方案,但我的实际项目中有很多属性和变量。
【解决方案3】:

与其拥有两个完全不同但名称不同的对象,不如研究如何进行对象继承

class Program
{
    static void Main(string[] args)
    {
        List<TestBase> lstTest = new List<TestBase>();

        lstTest.Add(new Test { Name = "j", Score = 2 });
        lstTest.Add(new Test2 { Name = "p", Score = 3 });
    }
}

class TestBase
{
    private string name;
    private int score;

    public string Name
    {
        get { return name;  }
        set { this.name = value; }
    }

    public int Score
    {
        get { return score; }
        set { this.score = value; }
    }
}

class Test : TestBase { }

class Test2 : TestBase { }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多