使用 LINQ 将 List<U> 转换为 List<T>

Posted

技术标签:

【中文标题】使用 LINQ 将 List<U> 转换为 List<T>【英文标题】:Using LINQ to convert List<U> to List<T> 【发布时间】:2011-10-27 21:10:25 【问题描述】:

我有 2 个具有相同属性的类。 我将第一类的属性存入列表中,然后,我想获取一些需要的属性并将它们放入第二类类型的列表中。 我已经通过 C# 制作了强制转换序列并且运行正常,但我必须使用 LINQ。我试图做一些事情,但没有好的结果。请帮我提建议。

一等奖:

   public class ServiceInfo 
    private long _id;
    public long ID 
        get  return this._id; 
        set  _id = value; 
    

    private string _name;
    public string Name 
        get  return this._name; 
        set  _name = value; 
    

    private long _qty;
    public long Quantity 
        get  return this._qty; 
        set  _qty = value; 
    

    private double _amount;
    public double Amount 
        get  return this._amount; 
        set  _amount = value; 
    

    private string _currency;
    public string Currency 
        get  return this._currency; 
        set  _currency = value; 
    

    private DateTime? _date;
    public DateTime? Date 
        get  return this._date; 
        set  _date = value; 
    

二等:

class InvoiceWithEntryInfo 
    private string currencyField;

    private long IdField;
    public long IdIWEI 
        get  return this.IdField; 
        set  IdIWEI = value; 
    

    private string nameField;
    public string NameIWEI 
        get  return this.nameField; 
        set  NameIWEI = value; 
    

    private long qtyField;
    public long QuantityIWEI 
        get  return this.qtyField; 
        set  QuantityIWEI = value; 
    

    private double amountField;
    public double AmountIWEI 
        get  return this.amountField; 
        set  AmountIWEI = value; 
    
    
    private DateTime dateField;
    public DateTime? DateIWEI 
        get  return this.dateField; 
        set  DateIWEI = value; 
    

    public string OwnerIWEI 
        get; set;
    

运行正常的 C# 示例: ...

var sil = new List<ServiceInfo>();
var iweil = new List<InvoiceWithEntryInfo>();

...

if (sil != null)
    
        foreach (ServiceInfo item in sil)
        
            iweil.Add(new InvoiceWithEntryInfo
                
                    IdIWEI = item.ID,
                    AmountIWEI = item.Amount,
                    DateIWEI = item.Date
                );
        

无法正常运行的 LINQ 示例:

iweilCOPY = sil.ConvertAll<InvoiceWithEntryInfo>(a => (InvoiceWithEntryInfo)a);

iweilCOPY = sil.FindAll(a => (sil is InvoiceWithEntryInfo)).ConvertAll<InvoiceWithEntryInfo>(a => (InvoiceWithEntryInfo)a);

【问题讨论】:

【参考方案1】:
var iweilCopy = sil.Select(item => new InvoiceWithEntryInfo()

  IdWEI = item.Id,
  NameWEI = item.Name,
  ....
).ToList();

【讨论】:

【参考方案2】:
  var iweil = sil.Select(item=> new InvoiceWithEntryInfo 
                 IdIWEI = item.ID,
                 AmountIWEI = item.Amount,
                 DateIWEI = item.Date).ToList();

【讨论】:

【参考方案3】:

您需要一个函数将T 实例转换为U 实例:

ResultType ConvertMethod(StartType input)

你需要写这个。那么

outputList = inputList.Select(ConvertMethod).ToList();

会将其应用于整个输入集合。转换函数可以是内联编写的 lambda,但不是必须的(如果函数具有正确的签名,例如 ConvertMethod,那么编译器将正确转换它以传递给 Select)。

【讨论】:

你能提供一些真实的例子吗?你的答案是最好的! List numbers = new List() 1, 2, 3 ; Func numToStringWithLPad = i => "数字:" + i; var numAsString = numbers.Select(numToStringWithLPad); numAsString.ToList().ForEach(i => Console.WriteLine(i));输出: 数量:1 数量:2 数量:3【参考方案4】:

只需使用选择:

if(sil != null)

   var iweil = sil.Select(item=>new InvoiceWithEntryInfo()
            
                IdIWEI = item.ID,
                AmountIWEI = item.Amount,
                DateIWEI = item.Date
            ).ToList();

【讨论】:

【参考方案5】:

您的常规 C# 代码和 LINQ 不等效。在常规 C# 中,您实例化另一个类的新实例并初始化属性,而您尝试从一个类转换(以及转换)到另一个;但是,由于它们不在同一个类层次结构中,因此您无法进行转换,并且由于您尚未定义转换运算符,因此您也无法转换(使用转换语法)。

你要么必须定义一个转换运算符

public static explicit operator InvoiceWithEntryInfo(ServiceInfo item)
     return new InvoiceWithEntryInfo 
             IdIWEI = item.ID,
             AmountIWEI = item.Amount,
             DateIWEI = item.Date;
 

或使用常规方法签名的创建方法。我建议后者,因为前者假装不是。这不是演员表,我个人希望能够看到代码根据一些输入创建一个新实例。

【讨论】:

以上是关于使用 LINQ 将 List<U> 转换为 List<T>的主要内容,如果未能解决你的问题,请参考以下文章

使用Linq确定序列是否包含任何元素

转C# Linq 交集并集差集去重

如何使用 LINQ 将 List<string> 中的所有字符串转换为小写?

C# 使用 LINQ 将 List<string> 的所有元素替换为相同的模式

C#中 list<object> 去除重复的数据 求最简单的方法!!

如何使用LINQ从列表中获取重复项?