web-dev-qa-db-fra.com

Utilisation de LINQ pour convertir List <U> en List <T>

J'ai 2 classes qui ont des propriétés identiques. Je stocke dans une liste les propriétés de la 1ère classe, et après cela, je veux prendre certaines propriétés nécessaires et les mettre dans une liste de type 2 classe. J'ai fait une séquence de distribution via C # et cela fonctionne bien, mais je dois le faire avec LINQ. J'ai essayé de faire quelque chose mais sans bons résultats. Aidez-moi s'il vous plaît avec des suggestions.

1ère classe:

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

2e classe:

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

Exemple C # qui fonctionne correctement: ...

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

Exemple LINQ qui ne fonctionne pas correctement:

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

            iweilCOPY = sil.FindAll(a => (sil is InvoiceWithEntryInfo)).ConvertAll<InvoiceWithEntryInfo>(a => (InvoiceWithEntryInfo)a);
45
mihai
var iweilCopy = sil.Select(item => new InvoiceWithEntryInfo()
{
  IdWEI = item.Id,
  NameWEI = item.Name,
  ....
}).ToList();
74
vc 74
  var iweil = sil.Select(item=> new InvoiceWithEntryInfo {
                 IdIWEI = item.ID,
                 AmountIWEI = item.Amount,
                 DateIWEI = item.Date}).ToList();
11
Bob Vale

Vous avez besoin d'une fonction pour convertir une instance T en une instance U:

ResultType ConvertMethod(StartType input)

et vous devez écrire ceci. ensuite

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

l'appliquera à l'ensemble de la collection d'entrées. La fonction de conversion peut être un lambda écrit en ligne mais ne doit pas l'être (si la fonction a la bonne signature, comme ConvertMethod alors le compilateur la convertira correctement pour passer à Select).

10
Richard

Utilisez simplement Select:

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

Votre code C # normal et LINQ ne sont pas équivalents. Dans le C # normal, vous instanciez une nouvelle instance de l'autre classe et initialisez les propriétés, tandis que vous essayez de transtyper (bien convertir) de l'une à l'autre; cependant, comme ils ne se trouvent pas dans la même hiérarchie de classes que vous ne pouvez pas convertir, et comme vous n'avez pas défini d'opérateur de conversion, vous ne pouvez pas non plus convertir (en utilisant la syntaxe de conversion).

Vous devez soit définir un opérateur de conversion

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

ou une méthode de création utilisant la signature de méthode régulière. Je suggérerais ce dernier puisque le premier prétend être quelque chose qu'il n'est pas. Ce n'est pas une distribution et j'aimerais personnellement pouvoir voir que le code crée une nouvelle instance basée sur une entrée.

2
Rune FS