【问题标题】:How do I map List<T1> to List<T2> using LINQ (or otherwise)如何使用 LINQ(或其他方式)将 List<T1> 映射到 List<T2>
【发布时间】:2015-04-14 16:25:10
【问题描述】:

最近我参与了一些涉及跨不同数据域转换对象的程序。所以我有很多映射方法(有时作为扩展方法)用于将一种类型的对象转换为不同域中的另一种类似类型。通常,我还需要一种将 List 转换为上述类型的 List 的方法。这总是涉及到一个方法,它简单地创建一个目标类型的 List,运行一个 foreach 循环来添加源 List 的每个元素(但在每个元素上使用映射方法)并返回新列表。感觉很重复,就像语言中可能内置了一些东西来做到这一点(也许在 LINQ 中?)。我已经研究了几个涉及 List.ForEach() 的类似问题以及它的优缺点(反正不是我想要的)。我将在下面用一些示例代码进行说明。也许没有办法做我想做的事,如果这是答案,那就是答案,但我希望也许有。请注意,这显然只是示例代码,关于我的整体程序设计的 cmets 不会真正添加任何内容,因为这是手头问题的一个非常小的虚拟版本。

class A
{
    public Guid Id { get; set; }
    public string Email { get; set; }
    public string MemberCode { get; set; }
}

class B
{
    public string Email { get; set; }
    public string MemberCode { get; set; }

    // My custom mapping method
    public A MapToA()
    {
        return new A()
        {
            Id = Guid.NewGuid(),
            Email = this.Email,
            MemberCode = this.MemberCode
        };
    }

    // For list mapping, I have this, but I'd prefer
    // to do something else that could utilize my custom mapper.
    // Perhaps a built in LINQ method?
    public static List<A> MapToListOfA(List<B> listOfB)
    {
        List<A> listOfA = new List<A>();

        foreach (var b in listOfB)
        {
            listOfA.Add(b.MapToA());
        }

        return listOfA;
    }
}

// Class C shows what I currently do that I'd like to get
// away from:
class C
{
    public List<A> ListOfA { get; set; }
    // other properties unrelated to the problem

    // This is how I might use the MapToListOfA method,
    // but I'd rather have something better.
    public C(List<B> listOfB)
    {
        this.ListOfA = B.MapToListOfA(listOfB);
    }
}

// I'd like something more like this:
class D
{
    public List<A> ListOfA { get; set; }
    // other properties unrelated to the problem

    public D(List<B> listOfB)
    {
        // This doesn't compile, of course, but I hope
        // it illustrates what I'm intending to do:
        this.ListOfA = listOfB.Select(b => b.MapToA());
    }
}

【问题讨论】:

  • 你看过 AutoMapper 吗??
  • 你的方法不错。只需添加对 .ToList() 的调用即可。
  • 我当然很喜欢这个网站上那些不加解释地投反对票的巨魔。请巨魔,看看stackoverflow.com/help/how-to-ask,告诉我我违反了哪一部分。我怀疑您对这个问题的问题是“您应该已经知道答案”。这是在提问网站上的一种很好的态度。尽管我非常喜欢这个社区,因为这些积极的人,这些点击快乐的反对者是一个巨大的关闭。
  • @EhsanSajjad - 不,我没有。我会检查一下。不过,我确实喜欢简单地做简单的事情,并且尽可能不使用库。

标签: c# linq list extension-methods


【解决方案1】:
// This doesn't compile, of course, but I hope
// it illustrates what I'm intending to do:
this.ListOfA = listOfB.Select(b => b.MapToA());

它无法编译,因为listOfB.Select(b =&gt; b.MapToA()) 产生了一个IEnumerable&lt;A&gt; 的实例,它不能分配给List&lt;A&gt;

使用ToList 应该可以正常编译

this.ListOfA = listOfB.Select(b => b.MapToA()).ToList();

【讨论】:

  • 额外信息:由于大多数映射方法是 Func(一个非 void 返回的输入),您可以在 Select 语句中使用映射方法本身而不是 lambda func . listOfB.Select(MapToA).ToList().
  • 这是我第一次如此迅速地得到正确答案,以至于我在几分钟内都无法选择它作为正确答案。
  • @ryanyuyu - 这实际上并没有为我编译。问题是 MapToA 是 B 的成员,因此必须在实例上调用吗?
  • @ryanyuyu 如果它是 public static A MapToA(B b) 而不是实例方法,那就可以了。
  • @bubbleking 啊,是的。就是这样。我只是习惯于将两种映射方法都作为static 成员(而不是实例)。我(错误地)假设由于 List 映射是静态的,因此单个对象的映射也是静态的。
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多