dies Nun schon gar nicht in C# unterstützt werden 4. Es gibt ein grundlegendes Problem ist:
List<Giraffe> giraffes = new List<Giraffe>();
giraffes.Add(new Giraffe());
List<Animal> animals = giraffes;
animals.Add(new Lion()); // Aargh!
Halten Giraffen sicher: nur nein sagen zu unsicher Varianz.
Die Array-Version funktioniert, weil Arrays do Referenzvarianz unterstützen, mit Laufzeitprüfung. Der Punkt der Generika ist Kompilierungszeit Typ Sicherheit.
In C# 4 gibt es Unterstützung für sichere generische Varianz, aber nur für Schnittstellen und Delegaten. So werden Sie in der Lage zu tun:
Func<string> stringFactory =() => "always return this string";
Func<object> objectFactory = stringFactory; // Safe, allowed in C# 4
Func<out T>
ist covariant in T
weil T
nur in einer Ausgangsposition verwendet. Vergleichen Sie das mit Action<in T>
der kontra ist in T
weil T
nur in einer Eingabeposition dort verwendet wird, so dass diese sicher:
Action<object> objectAction = x => Console.WriteLine(x.GetHashCode());
Action<string> stringAction = objectAction; // Safe, allowed in C# 4
IEnumerable<out T>
ist covariant als auch, so dass diese korrekt in C# 4, wie von anderen darauf hingewiesen:
IEnumerable<Animal> animals = new List<Giraffe>();
// Can't add a Lion to animals, as `IEnumerable<out T>` is a read-only interface.
in Bezug auf die in Ihrer Situation in C# 2, um dieses arbeiten, tun Sie eine Liste zu halten brauchen, oder würden Sie gerne eine neue Liste zu erstellen? Wenn das akzeptabel ist, ist List<T>.ConvertAll
dein Freund.
+1 nur um Jons Antwort hinzuzufügen (nicht, dass er irgendeine Hilfe braucht), dem "Func' '' '' Func
Danke, dass Sie auch auf das Typsicherheitsproblem hingewiesen haben. Das ist sehr hilfreich. – AndiDog
Was stimmt nicht mit 'animals.Add (new Lion()); // Aargh! '? Wenn du einen 'Löwen' wirken und ihn als' Tier' verwenden kannst, und wenn du alle Elemente in 'Tiere' als 'Tier' verwendest, was ist dann das Problem? – Jeff