Using LINQ to convert List<U> to List<T>

83,773

Solution 1

var iweilCopy = sil.Select(item => new InvoiceWithEntryInfo()
{
  IdWEI = item.Id,
  NameWEI = item.Name,
  ....
}).ToList();

Solution 2

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

Solution 3

You need a function to convert a T instance to a U instance:

ResultType ConvertMethod(StartType input)

and you need to write this. Then

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

will apply it to the whole input collection. The conversion function can be a lambda written inline but doesn't need to be (if the function has the right signature, like ConvertMethod then the compiler will convert it correctly to pass to Select).

Solution 4

Just use Select:

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

Solution 5

Your regular C# code and LINQ are not equivalent. In the regular C# you instantiate a new instance of the other class and initialize the properties, whereas you try to cast (well convert) from one to the other; however, since they are not in the same class hierarchy you can't cast, and as you haven't defined a conversion operator, you can't convert (using cast syntax) either.

You either have to define a conversion operator

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

or a creation method using regular method signature. I'd suggest the latter since the former pretend to be something it's not. It's not a cast and I'd personally like to be able to see that the code creates a new instance based on some input.

Share:
83,773
mihai
Author by

mihai

Software Engineer /REST API in C# .NET, Angular 2+, Microservices, SQL Databases and Azure Storage, Azure AppInsights, Azure CI/CD/

Updated on July 09, 2022

Comments

  • mihai
    mihai almost 2 years

    I have 2 classes which have some identical properties. I stock into a list properties from 1st class, and after that, I want to take some needed properties and put them into a list of 2nd class type. I've made cast sequence through C# and that runs OK, but I must do with LINQ. I tried to do something but without good results. Help me please with suggestions.

    1st Class:

       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; }
        }
    }
    

    2nd Class:

    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# sample which runs OK: ...

    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 sample which doesn't run OK:

    iweilCOPY = sil.ConvertAll<InvoiceWithEntryInfo>(a => (InvoiceWithEntryInfo)a);
    
    iweilCOPY = sil.FindAll(a => (sil is InvoiceWithEntryInfo)).ConvertAll<InvoiceWithEntryInfo>(a => (InvoiceWithEntryInfo)a);
    
  • NoWar
    NoWar over 10 years
    Could you provide some real example, pls? Your answer is the best one!
  • Win Man
    Win Man about 7 years
    List<int> numbers = new List<int>() { 1, 2, 3 }; Func<int, string> numToStringWithLPad = i => "Number: " + i; var numAsString = numbers.Select(numToStringWithLPad); numAsString.ToList().ForEach(i => Console.WriteLine(i)); Output: Number: 1 Number: 2 Number: 3