【问题标题】:Hide multiple classes behind one interface [duplicate]在一个接口后面隐藏多个类[重复]
【发布时间】:2015-12-19 13:02:18
【问题描述】:

这是我正在尝试做的一个示例:

public interface IChildItem
{}

public interface IItem
{
    public EntitySet<IChildItem> Children {get;}
}

public class ChildItem1 : IChildItem
{}

public class ChildItem2 : IChildItem
{}

public class Item1 : IItem
{
    public EntitySet<ChildItem1> Children
    {
        get{ return m_children; }
    }
}

public class Item2 : IItem
{
    public EntitySet<ChildItem2> Children
    {
        get{ return m_children; }
    }
}

我正在尝试将 Item1 和 Item2 隐藏在 IItem 界面后面。

主要问题是我还需要 Children 属性来返回接口列表 (IChildItem)。但是编译器说我这样做的方式是不允许的。在 Item1 和 Item2 类中缺少 EntitySet&lt;IChildItem&gt; Children {get;}。为什么EntitySet&lt;ChildItem1&gt;不等于EntitySet&lt;IChildItem&gt;???

类 Item1 和 Item2 是自动生成的 (dbml),这就是我无法更改它们的原因。

有什么技巧可以帮我解决这个问题吗?

【问题讨论】:

  • 你能改变接口的定义吗?
  • @Sergii Zhevzhyk:是的!!
  • 您可以创建一个可以同时容纳 Item1 和 Item2 的持有者类,并给它一个“通用”接口。我认为这被称为外观模式
  • @walruz 你能改变这条线public class Item1 : IItem吗?或者它是一代人的一部分?
  • “为什么EntitySet&lt;ChildItem1&gt; 不等于EntitySet&lt;IChildItem&gt;?” - 因为它们不是。实现接口时,必须实现完全相同的类型。它们是协变的并不意味着它们是相同的。

标签: c#


【解决方案1】:

通用接口是解决方案:

public interface IChildItem
{ }

public interface IItem<T> where T: class
{
    List<T> Children { get; }
}

public class ChildItem1 : IChildItem
{ }

public class ChildItem2 : IChildItem
{ }

public class Item1 : IItem<ChildItem1>
{
    public List<ChildItem1> Children
    {
        get { return null; }
    }
}

public class Item2 : IItem<ChildItem2>
{
    public List<ChildItem2> Children
    {
        get { return null; }
    }
}

【讨论】:

    【解决方案2】:

    您可以使用GenericsCovariance 来执行此操作

    public interface IChildItem                                              
    { }                                                                      
    
    public interface IItem<out TChild> where TChild : IChildItem             
    {                                                                        
        IEnumerable<TChild> Children { get; }                                
    }                                                                        
    
    public class ChildItem1 : IChildItem                                     
    { }                                                                      
    
    public class ChildItem2 : IChildItem                                     
    { }                                                                      
    
    public class Item1 : IItem<ChildItem1>                                   
    {                                                                        
        public IEnumerable<ChildItem1> Children                              
        {                                                                    
            get { return null; }                                             
        }                                                                    
    }                                                                        
    
    public class Item2 : IItem<ChildItem2>                                   
    {                                                                        
        public IEnumerable<ChildItem2> Children                              
        {                                                                    
            get { return null; }                                             
        }                                                                    
    }                                                                        
    
    IItem<ChildItem1> variable = new Item1();                                
    IItem<IChildItem> variable2 = variable;                                
    

    【讨论】:

      猜你喜欢
      • 2013-01-07
      • 1970-01-01
      • 2017-07-09
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      相关资源
      最近更新 更多