public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Come posso trasmettere List<Client>
a List<IDic>
?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Come posso trasmettere List<Client>
a List<IDic>
?
Risposte:
Non puoi lanciarlo (preservando l'identità di riferimento) - non sarebbe sicuro. Per esempio:
public interface IFruit {}
public class Apple : IFruit {}
public class Banana : IFruit {}
...
List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());
// Eek - it's a banana!
Apple apple = apples[0];
Ora puoi convertire a List<Apple>
in un IEnumerable<IFruit>
in .NET 4 / C # 4 a causa della covarianza, ma se vuoi un List<IFruit>
dovresti creare un nuovo elenco. Per esempio:
// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();
// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();
Ma questo non è lo stesso che lanciare l'elenco originale, perché ora ci sono due elenchi separati . Questo è sicuro, ma è necessario comprendere che le modifiche apportate a un elenco non verranno visualizzate nell'altro elenco. ( Ovviamente si vedranno le modifiche agli oggetti a cui fanno riferimento gli elenchi.)
List<IFruit>
che in realtà era un riferimento a un file List<Apple>
. Cosa ti aspetteresti che succeda se aggiungessi un Banana
riferimento a questo List<IFruit>
?
using
direttiva per System.Linq
, o come stai cercando di chiamarlo, non sono sicuro di come ti aspetti che io sia in grado di aiutarti. Ti suggerisco di fare più ricerche e, se sei ancora bloccato, fai una domanda con un esempio riproducibile minimo .
Un iteratore Cast e .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
farà il trucco.
Inizialmente ho detto che la covarianza avrebbe funzionato, ma come ha giustamente sottolineato Jon; no non lo farà!
E originariamente ho anche interrotto stupidamente la ToList()
chiamata
Cast
restituisce an IEnumerable<T>
, non a List<T>
- e no, la covarianza non consentirà questa conversione, perché non sarebbe sicura - vedi la mia risposta.
ToList()
mancava prima di leggere il tuo commento; ma sì, come hai dimostrato, ovviamente la covarianza non funzionerà! Doh!
Cast
chiamata in .NET 4, purché si specifichi l'argomento di tipo a ToList
.
Anch'io ho avuto questo problema e dopo aver letto la risposta di Jon Skeet ho modificato il mio codice dall'uso List<T>
all'uso IEnumerable<T>
. Anche se questo non rispondere alla domanda originale del PO di Come posso lanciare List<Client>
aList<IDic>
, lo fa evitare la necessità di farlo e quindi potrebbe essere utile ad altri che si verifichi questo problema. Questo ovviamente presuppone che il codice che richiede l'uso diList<IDic>
sia sotto il tuo controllo.
Per esempio:
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
Invece di:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
È possibile solo creando nuovi List<IDic>
e trasferendo tutti gli elementi.
In .Net 3.5, puoi fare quanto segue:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Il costruttore di List in questo caso accetta un IEnumerable.
list è però convertibile solo in IEnumerable. Anche se myObj può essere convertibile in ISomeInterface, il tipo IEnumerable non è convertibile in IEnumerable.