2016-12-08 2 views
0

Angenommen, wir haben folgende Schnittstelle:Generic Interface mit Array von Generika

public interface ILine<T> 
{ 
    T Item { get; set;} 
} 

Ich habe tun Klassen Line1 und Line2 deren Umsetzung

public class Item1 
{ 
} 

public class Item2 
{ 
} 

public class Line1 : ILine<Item1> 
{ 
    public Item1 Item {get; set;} 
} 

public class Line2 : ILine<Item2> 
{ 
    public Item2 Item { get; set; } 
} 

Jetzt habe ich eine Klasse

public class Lines1 
{ 
    public Line1[] Items { get; set;} 
} 

Ich möchte eine Schnittstelle

erstellen
public interface ILines<T> 
{ 
    ILine<T>[] Items { get; set;} 
} 

Und lassen Lines1 implementieren es Lines1 : ILines<Item1> (und Lines2 das gleiche tun mit Item2). Aber es ist nicht möglich, wegen Compiler-Fehler

'Lines1' implementiert nicht Schnittstelle Mitglied 'ILines.Items'. 'Lines1.Items' kann 'ILines.Items' nicht implementieren, da nicht den passenden Rückgabetyp von 'IEnumerable>' aufweist.

Die Klassen werden aus XML deserialisiert, so dass ich wirklich brauchen Eigenschaften wie Item1, Item2, Line1, Line2 nicht als Schnittstellen. Was könnte ich tun, um vorwärts zu gehen? Oder ich versuche, ein berühmtes Antipattern anzuwenden?

aktualisieren: Sehr gute Erklärung, warum es nicht möglich ist: covariance in c#

Leider habe ich es nicht vor dem Schreiben Frage gefunden.

Antwort

1

ILine<T>[] ist nicht dasselbe wie Line1[]. Es gibt viele Antworten auf SO über das Konzept der Varianz, sie können dies deutlich erklären.

Die Lösung besteht darin, sicherzustellen, dass die Typen tatsächlich einander zugeordnet werden. Eine Möglichkeit, dies zu tun, ist Line1 ein allgemeines Argument sowie zu machen:

interface ILines<T, U> where U : ILine<T> 
{ 
    U[] Items { get; set; } 
} 

Leider dies bedeutet, dass Sie etwas von der Art Schlußfolgerungs verlieren, so kann es durchaus ein bisschen mehr Text bedeuten.

0
You may want to check this out.  

    public class LinesOne : ILines<Item1> 
     { 
      public ILine<Item1>[] Lines 
      { 
       get 
       { 
        throw new NotImplementedException(); 
       } 

       set 
       { 
        throw new NotImplementedException(); 
       } 
      } 
     } 

     public class LinesTwo : ILines<Item2> 
     { 
      public ILine<Item2>[] Lines 
      { 
       get 
       { 
        throw new NotImplementedException(); 
       } 

       set 
       { 
        throw new NotImplementedException(); 
       } 
      } 
     } 
     public interface ILines<T> 
     { 

      ILine<T>[] Lines { get; set; } 
     } 

     public interface ILine<T> 
     { 
      T Item { get; set; } 
     } 

     public class Item1 
     { 
     } 

     public class Item2 
     { 
     } 

     public class Line1 : ILine<Item1> 
     { 
      public Item1 Item { get; set; } 
     } 

     public class Line2 : ILine<Item2> 
     { 
      public Item2 Item { get; set; } 
     } 
+0

Das ist nicht das, was ich erreichen möchte. Sie schlagen vor, öffentliche ILine zu verwenden [] Linien und ich brauche public Line1 [] Items {bekommen; einstellen;} . Der Serializer, der Objekte erstellt, weiß, welche Klasse Line1 ist, konnte aber keine Instanzen einer Schnittstelle erstellen. –