Using LINQ to convert List<U> to List<T>
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);
var iweilCopy = sil.Select(item => new InvoiceWithEntryInfo()
{
IdWEI = item.Id,
NameWEI = item.Name,
....
}).ToList();
var iweil = sil.Select(item=> new InvoiceWithEntryInfo {
IdIWEI = item.ID,
AmountIWEI = item.Amount,
DateIWEI = item.Date}).ToList();
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
).
Just use Select:
if(sil != null)
{
var iweil = sil.Select(item=>new InvoiceWithEntryInfo()
{
IdIWEI = item.ID,
AmountIWEI = item.Amount,
DateIWEI = item.Date
}).ToList();
}
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.