2009-07-15 18 views
3

Ich habe folgendes Erbe:Warum schlägt dieser generische Cast fehl?

internal abstract class TeraRow{} 

internal class xRow : TeraRow {} // xRow is a child of TeraRow 

public IEnumerable<TeraRow> Compare(MappedTables which, DateTime selectionStart 
     , DateTime selectionEnd, string pwd) 
{ 
    IEnumerable<xRow> result=CompareX(); 
    return (IEnumerable<TeraRow>)result; //Invalid Cast Exception? 

} 

Kann nicht das Objekt des Typs ‚System.Collections.Generic.List 1[xRow]' to type 'System.Collections.Generic.IEnumerable 1 [TeraRow]

auch, warum ich es überhaupt werfen müssen werfen?

+0

Diese Art von Besetzung wird in C# 4.0 unterstützt und später in diesem Jahr veröffentlicht. Die Funktion, die dieses Problem anspricht, wird als kovariante generische Argumente bezeichnet. –

Antwort

16

Sie müssen es werfen, weil IEnumerable<T> nicht auf T. kovariant Sie dies tun können:

return result.Cast<TeraRow>(); 
+0

Downcasting generische typisierte Listen ... Einer der wenigen Orte, an denen Generika auseinanderfallen, ohne explizit Composite-Schnittstellen zu definieren. –

0

Wenn Sie die ausgeführte Liste wie die ursprüngliche Referenz ausführen möchten (das Festlegen eines Elements in einem Index legt auch das Element in der ursprünglichen Auflistung fest, können Sie eine Wrapperklasse erstellen, die IList < T implementiert > (Es sei denn, ich etwas fehle), für allgemeine Zwecke Lösung Sie werden aufgrund von Einschränkungen generische Einschränkung zwei benötigen.

public class UpCastList<FromType, ToType> : IList<ToType> 
    where FromType : ToType 

public class DownCastList<FromType, ToType : IList<ToType> 
    where ToType : FromType 

die andere Möglichkeit, die Umwandlung delegiert:

public class CastList<FromType, ToType> : IList<ToType> 
{ 
    public CastList(IList<FromType> source, Func<FromType, ToType> converter) { ... } 
} 

Edit: Wenn Sie nur eine IEnumerable <T> benötigen, können Sie die Cast <T> Erweiterung Methode wie bereits erwähnt verwenden.

Verwandte Themen