2016-12-08 2 views
0

Предположим, мы имеем следующие интерфейс:Общий интерфейс с множеством дженериков

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

У меня есть классы Line1 и Line2 реализующие его

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; } 
} 

Теперь у меня есть класс

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

Я хотел бы создать интерфейс

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

И пусть Lines1 реализовать Lines1 : ILines<Item1>Lines2 делать то же самое с Item2). Но это невозможно, из-за ошибки complier

«Линии1» не реализует интерфейсный элемент «ILines.Items». 'Lines1.Items' не может реализовать 'ILines.Items', потому что не имеет соответствующего типа возврата 'IEnumerable>'.

Классы десериализации из XML, так что я на самом деле нужны свойства, как Item1, Item2, Line1, Line2 не в качестве интерфейсов. Что я могу сделать, чтобы идти вперед? Или я пытаюсь применить какой-то знаменитый антипаттерн?

Update: Очень хорошее объяснение, почему это не представляется возможным: covariance in c#

К сожалению, я не нашел его, прежде чем писать вопрос.

ответ

1

ILine<T>[] не то же самое, что Line1[]. На SO есть много ответов о концепции variance, они могут это ясно объяснить.

Решение состоит в том, чтобы убедиться, что типы фактически сопоставляются друг с другом. Один из способов сделать это, чтобы сделать Line1 общий аргумент, а:

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

К сожалению, это означает, что вы потеряете часть типа inferrence, так что это может означать совсем немного дополнительный текст.

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

Это не то, чего я хочу достичь. Вы предлагаете использовать public ILine [] Линии и мне нужна публичная линия1 [] Элементы {get; задавать;} . Сериализатор, который создает объекты, знает, что такое класс Line1, но не смог создать экземпляры интерфейса. –

Смежные вопросы