【问题标题】:convert a list of objects from one type to another using lambda expression使用 lambda 表达式将对象列表从一种类型转换为另一种类型
【发布时间】:2009-12-15 18:06:13
【问题描述】:

我有一个 foreach 循环读取一种类型的对象列表并生成不同类型的对象列表。有人告诉我 lambda 表达式可以达到相同的结果。

var origList = List<OrigType>(); // assume populated
var targetList = List<TargetType>(); 

foreach(OrigType a in origList) {
    targetList.Add(new TargetType() {SomeValue = a.SomeValue});
}

任何帮助将不胜感激 - 我是 lambda 和 linq 的新手 谢谢, s

【问题讨论】:

  • @mmcrae 这个问题比这个问题新

标签: c# generics lambda


【解决方案1】:

试试下面的

var targetList = origList
  .Select(x => new TargetType() { SomeValue = x.SomeValue })
  .ToList();

这是使用 Lambdas 和 LINQ 的组合来实现的解决方案。 Select 函数是一种投影样式方法,它将传入的委托(或在本例中为 lambda)应用于原始集合中的每个值。结果将在新的IEnumerable&lt;TargetType&gt; 中返回。 .ToList 调用是一种扩展方法,它将将此IEnumerable&lt;TargetType&gt; 转换为List&lt;TargetType&gt;

【讨论】:

  • 有没有办法在没有TargetType 的具体实现的情况下做到这一点?我最终得到了这样的结果:List&lt;ISearchEntity&gt; results = myIQueryable.Select(x =&gt; (ISearchEntity) new TargetType { MyField = "Field value is " + x.TargetField }).ToList();,目标是获取 List&lt;ISearchEntity&gt; 类型的对象
【解决方案2】:

如果您知道您想从List&lt;T1&gt; 转换为List&lt;T2&gt;,那么List&lt;T&gt;.ConvertAll 将比Select/ToList 稍微高效一些,因为它知道开始的确切大小与:

target = orig.ConvertAll(x => new TargetType { SomeValue = x.SomeValue });

在更一般的情况下,当您只知道源为 IEnumerable&lt;T&gt; 时,使用 Select/ToList 是可行的方法。您也可以争辩说,在使用 LINQ 的世界中,从一开始就更符合习惯......但至少值得了解 ConvertAll 选项。

【讨论】:

  • 起初我不认为我能做到这一点,因为我正在处理一个 ienumerable (对于源列表并且它不提供 convertall 选项)所以我在它上面调用了 .ToList() 并且现在我正在尝试 convertall - 我更喜欢它而不是放入一个非过滤的 'where'
  • 你为什么需要一个where?如果您只有 IEnumerable&lt;T&gt;,那么只需按照 Jared 的回答致电 SelectToList
  • 像我这样的新手,也可以调用x =&gt; buildTargetType(x)这样的方法
【解决方案3】:
var target = origList.ConvertAll(x => (TargetType)x);

【讨论】:

  • 这是什么语法?这不像 lambda。一些文档链接将不胜感激。不过谢谢,这里工作正常
  • ConvertAll 的参数是一个常规的 C# lambda,对吧?
  • 看起来不错,但需要一些关于何时(或是否)可以使用它的上下文。我刚试了一下,得到了cannot cast expression 异常
【解决方案4】:
List<target> targetList = new List<target>(originalList.Cast<target>());

【讨论】:

  • -1 这只有在可以进行强制转换的情况下才有效,并且在 OPs 的情况下确实如此。
  • 按预期工作!需要将 List 转换为 List
  • 请注意,此答案仅在 TargetTypeOrigType 的基本类型时才有效。可以简化为... = originalList.Cast&lt;TargetType&gt;().ToList();
【解决方案5】:

我相信这样的事情应该可行:

origList.Select(a => new TargetType() { SomeValue = a.SomeValue});

【讨论】:

  • 你需要在最后添加一个.ToList(),否则这只会提供一个IEnumerable。
【解决方案6】:

这是一个简单的例子..

List<char> c = new List<char>() { 'A', 'B', 'C' };

List<string> s = c.Select(x => x.ToString()).ToList();

【讨论】:

  • 太棒了...正是我想要的!嗯,不完全是……我只是想要列表中每个元素的属性,但是你给了我 Lamba 语法,而不必滚动太远。 ;)
【解决方案7】:
var list1 = new List<Type1>();
var list2 = new List<Type2>();

list1.ForEach(item => list2.Add(new Type2() { Prop1 = value1 }));

【讨论】:

    【解决方案8】:

    假设您有多个要转换的属性。

    public class OrigType{
        public string Prop1A {get;set;}
        public string Prop1B {get;set;}
    }
    
    public class TargetType{
        public string Prop2A {get;set;}
        public string Prop2B {get;set;}
    }
    
    var list1 = new List<OrigType>();
    var list2 = new List<TargetType>();
    
    list1.ConvertAll(x => new OrigType { Prop2A = x.Prop1A, Prop2B = x.Prop1B })
    

    【讨论】:

      【解决方案9】:

      或者constructor & linqSelect

      public class TargetType {
        public string Prop1 {get;set;}
        public string Prop1 {get;set;}
      
        // Constructor
        public TargetType(OrigType origType) {
          Prop1 = origType.Prop1;
          Prop2 = origType.Prop2;
        }
      }
      
      var origList = new List<OrigType>();
      var targetList = origList.Select(s=> new TargetType(s)).ToList();  
      

      Linq 线更软! ;-)

      【讨论】:

        【解决方案10】:

        如果需要使用函数进行强制转换:

        var list1 = new List<Type1>();
        var list2 = new List<Type2>();
        
        list2 = list1.ConvertAll(x => myConvertFuntion(x));
        

        我的自定义函数在哪里:

        private Type2 myConvertFunction(Type1 obj){
           //do something to cast Type1 into Type2
           return new Type2();
        }
        

        【讨论】:

        • 可以进一步缩短,list2 = list1.ConvertAll(myConvertFuntion);
        【解决方案11】:

        对于类似类型的类。

        List&lt;targetlist&gt; targetlst= JsonConvert.DeserializeObject&lt;List&lt;targetlist&gt;&gt;(JsonConvert.SerializeObject(&lt;List&lt;baselist&gt;));

        【讨论】:

        • 非常感谢。它对于服务器来说非常昂贵,而且它不符合最佳实践,但工作出色。当多个过程返回相同的 5 列结果时,我使用它来转换 EF 数据库第一类,仅用于过程中的不同“where 子句”。我知道我应该在数据库上创建表类型,但我不是那个的设计者..
        【解决方案12】:

        如果可以直接转换类型,这是最简洁的方法:

        var target = yourList.ConvertAll(x => (TargetType)x);
        

        如果无法直接转换类型,则可以将属性从原始类型映射到目标类型。

        var target = yourList.ConvertAll(x => new TargetType { SomeValue = x.SomeValue });
        

        【讨论】:

          【解决方案13】:

          我们将考虑第一个List类型是String,并希望将其转换为List的Integer类型。

          List<String> origList = new ArrayList<>(); // assume populated
          

          在原始列表中添加值。

          origList.add("1");
          origList.add("2");
              origList.add("3");
              origList.add("4");
              origList.add("8");
          

          创建整数类型的目标列表

          List<Integer> targetLambdaList = new ArrayList<Integer>();
          targetLambdaList=origList.stream().map(Integer::valueOf).collect(Collectors.toList());
          

          使用 forEach 打印列表值:

              targetLambdaList.forEach(System.out::println);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-05-21
            • 1970-01-01
            • 2010-09-23
            • 1970-01-01
            • 2011-01-24
            • 1970-01-01
            相关资源
            最近更新 更多