public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Wie kann ich werfen List<Client>
zu List<IDic>
?
Sie können es nicht umsetzen (Referenzidentität bewahren) - das wäre unsicher. Beispielsweise:
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];
Jetzt können Sie aufgrund von Kovarianz eine List<Apple>
in eine IEnumerable<IFruit>
in .NET 4 / C # 4 konvertieren. Wenn Sie jedoch eine möchten, müssen List<IFruit>
Sie eine neue Liste erstellen . Beispielsweise:
// 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();
Dies ist jedoch nicht dasselbe wie das Casting der ursprünglichen Liste - da es jetzt zwei separate Listen gibt. Dies ist sicher, aber Sie müssen verstehen, dass Änderungen an einer Liste nicht in der anderen Liste angezeigt werden. (Änderungen an den Objekten , auf die sich die Listen beziehen, werden natürlich angezeigt.)
List<IFruit>
die tatsächlich eine Referenz auf a warList<Apple>
. Was würden Sie erwarten, wenn Sie einenBanana
Verweis darauf hinzufügen würdenList<IFruit>
?using
Richtlinie fürSystem.Linq
, oder was Sie versuchen , es zu nennen, ich bin sicher , dass nicht , wie du mich erwarten zu Hilfe zu können. Ich schlage vor, Sie recherchieren mehr und wenn Sie immer noch nicht weiterkommen, stellen Sie eine Frage mit einem minimal reproduzierbaren Beispiel .Ein Cast-Iterator und .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
wird den Trick machen.Ursprünglich sagte ich, Kovarianz würde funktionieren - aber wie Jon zu Recht betont hat; nein wird es nicht!
Und ursprünglich habe ich den
ToList()
Anruf auch dumm abgebrochenquelle
Cast
eine RenditeIEnumerable<T>
, keineList<T>
- und nein, Kovarianz nicht um diese Umwandlung zu ermöglichen, da es unsicher wäre - meine Antwort sehen.ToList()
fehlte, bevor ich Ihren Kommentar gelesen habe. Aber ja, wie Sie gezeigt haben, funktioniert Covariance natürlich nicht! Doh!Cast
Aufruf in .NET 4 nicht benötigen , solange Sie das Typargument angebenToList
.Auch ich hatte dieses Problem und nachdem ich Jon Skeets Antwort gelesen hatte, änderte ich meinen Code von der Verwendung
List<T>
zur VerwendungIEnumerable<T>
. Obwohl dies nicht die OP ursprüngliche Frage beantwortet Wie kann ich werfenList<Client>
zuList<IDic>
, ist es die Notwendigkeit zu vermeiden , dies zu tun, und kann somit für andere hilfreich sein , die dieses Problem auftreten. Dies setzt natürlich voraus, dass der Code, für den die Verwendung erforderlichList<IDic>
ist, unter Ihrer Kontrolle steht.Z.B:
Anstatt:
quelle
Wenn Sie LINQ verwenden können, können Sie dies tun ...
quelle
quelle
Es ist nur möglich, indem Sie neue
List<IDic>
Elemente erstellen und alle Elemente übertragen.quelle
In .Net 3.5 können Sie Folgendes tun:
Der Konstruktor für List verwendet in diesem Fall eine IEnumerable.
Liste ist jedoch nur in IEnumerable konvertierbar. Obwohl myObj möglicherweise in ISomeInterface konvertierbar ist, kann der Typ IEnumerable nicht in IEnumerable konvertiert werden.
quelle