【问题标题】:Generic Interface with array of generics具有泛型数组的泛型接口
【发布时间】:2016-12-09 15:07:47
【问题描述】:

假设我们有以下界面:

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

我确实有课程 Line1Line2 实现它

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&lt;Item1&gt;Lines2Item2 执行相同的操作)。但这是不可能的,因为编译器错误

“Lines1”没有实现接口成员“ILines.Items”。 'Lines1.Items' 不能实现 'ILines.Items' 因为它确实 没有匹配的返回类型“IEnumerable>”。

这些类是从 xml 反序列化的,所以我真的需要 Item1Item2Line1Line2 等属性而不是接口。 我能做些什么来前进?或者我正在尝试应用一些著名的反模式?

更新:很好的解释,为什么不可能: covariance in c#

很遗憾在写问题之前我没有找到它。

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    ILine&lt;T&gt;[]Line1[] 不同。关于方差的概念,SO上有很多答案,他们可以清楚地解释这一点。

    解决方案是确保类型实际上相互映射。一种方法是使Line1 也成为通用参数:

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

    遗憾的是,这意味着您丢失了一些类型推断,因此可能意味着相当多的额外文本。

    【讨论】:

      【解决方案2】:
      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; }
              }
      

      【讨论】:

      • 这不是我想要达到的。您建议使用 public ILine[] Lines,我需要 public Line1[] Items { get;放;} 。创建对象的序列化程序知道 Line1 类是什么,但无法创建接口的实例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多