2014-01-20 11 views
11
private static void TestStructInterface() 
{ 
    IFoo foo1 = new FooClass(); // works 
    IFoo foo2 = new FooStruct(); // works 
    IEnumerable<IFoo> foos1 = new List<FooClass>(); // works 
    IEnumerable<IFoo> foos2 = new List<FooStruct>(); // compiler error 
} 

interface IFoo 
{ 
    string Thing { get; set; } 
} 

class FooClass : IFoo 
{ 
    public string Thing { get; set; } 
} 

struct FooStruct : IFoo 
{ 
    public string Thing { get; set; } 
} 

Der Compiler beschwert Umsetzung:Struct vs Klasse eine Schnittstelle

kann nicht implizit konvertiert Typ 'System.Collections.Generic.List <Tests.Program.FooStruct>' auf ‚System.Collections.Generic. IEnumerable <Tests.Programm.IFoo> '. Es gibt eine explizite Konvertierung (fehlt Ihnen ein Cast?)

Warum?
Warum gibt es einen Unterschied zwischen Klassen und Strukturen? Problemumgehungen?

+0

siehe Frage SO http://stackoverflow.com/questions/13049/whats-the-difference-between-struct-and-class-in-net Und akzeptierte Antwort: http://stackoverflow.com/a/13275/1155847 –

+0

Auch hier: http://stackoverflow.com/questions/9688268/why-cannot-ienumerablestruct-be-cast-as-ienumerableobject –

+2

Nur eine Nebensache über Terminologie: Schnittstellen sind "implementiert", nicht "vererbt". –

Antwort

2

Genau wie Bharathram Attiyannan antwortete, wird die Varianz für Werttypen einfach nicht unterstützt.

Die Abhilfe ist einfach:

List<FooStruct> listOfFooStruct = new List<FooStruct>(); 
IEnumerable<IFoo> enumerableOfFoo = listOfFooStruct.Cast<IFoo>(); 
1

Dies wurde bereits hier beantwortet - Why covariance and contravariance do not support value type, aber zusammenfassen für ein einfacheres Nachschlagen.

Das Verhalten, das Sie implementieren möchten, heißt Varianz.

Dies ist aufgrund einer Beschränkung in CLR erzwungen, die in Eric Lippert's Blog erklärt -

Covariant und kontra Umwandlungen von Schnittstellen- und delegieren erfordern Typen, die alle Argumente von Referenz Typen variierender Typ

Der Grund wird in MSDN erklärt:

Varianz App liegt nur an Referenztypen; Wenn Sie für einen Variant-Typparameter einen Werttyp angeben, ist dieser Typparameter für den resultierenden konstruierten Typ invariant.

+0

Danke für die Erklärung. Haben Sie einen Vorschlag für eine Problemumgehung? –

+0

Sorry konnte nicht die genaue Lösung für Sie trainieren .. Aber von dem, was ich verstehe, müssen Sie explizit Cast Struct Class eingeben. Diese Antwort könnte Ihnen helfen - http://Stackoverflow.com/a/9688362/442444 – CarbineCoder

Verwandte Themen