【问题标题】:Adding a Collection of Interfaces to an Interface将接口集合添加到接口
【发布时间】:2012-11-02 11:25:11
【问题描述】:

我正在尝试围绕接口进行思考。我一直在暗示这样的事情:

public interface IFoo
{
    ICollection<IBar> Bars { get; set; }
    //some other properties
}
public interface IBar
{
    //some properties
}
//assume Bar is implemented and extends IBar. Some instaces of Bar are created
Bar[] MyBars = {bar1, bar2};
Foo MyFoo = new Foo();
MyFoo.Bars=MyBars.ToList(); //This causes an error saying Collection<Bar> cannot be
//assigned to ICollection<IBar>.

我完全不知道如何正确地做到这一点。填充接口集合的正确方法是什么?

编辑:我实现 Foo 的方式可能是问题的一部分。

public class Foo : IFoo
{
    public ICollection<IBar> Bars { get; set; }
}

【问题讨论】:

  • 您是否尝试使用 Collection 而不是 ICollection
  • @Fuex foo 类可能是问题的一部分。一分钟。
  • 您正在尝试将Bar 的集合放入IBar 的集合中。编译器不能假定接口可以隐式转换。
  • 我接受了他的评论://假设 Foo 和 Bar 已实现并扩展 IFoo 和 IBar,并创建了一些 //Bar 的实例 ... 以表明他已经知道并且已经这样做了。
  • 你试过我下面的建议了吗?

标签: c# interface icollection


【解决方案1】:

问题是Foo 类应该是:

public class Foo : IFoo
{
    public ICollection<Bar> Bars { get; set; }
}

或者如果你想使用ICollection&lt;IBar&gt;:

IBar[] MyBars = { bar1, bar2 };
Foo MyFoo = new Foo( );
MyFoo.Bars = MyBars.ToList( );

或者更优雅的解决方案:

Bar[] MyBars = { bar1, bar2 };
Foo MyFoo = new Foo( );
MyFoo.Bars = MyBars.ToList<IBar>( ); //Cast from Bar to IBar

事实上,问题的发生是因为您无法将 ICollection&lt;Bar&gt; 转换为 ICollection&lt;IBar&gt;

【讨论】:

  • 请注意:Foo 不能有一个名为 Bars 的属性与 IFoo 的名为 Bars 的属性的类型不同。
【解决方案2】:

您如何实现 Bars 属性在这里很重要。您不能将具体类型分配给接口类型。当您尝试进行 ToList 转换时,您正在将其转换为具体列表类型并尝试将其分配给 ICollection 接口类型,因此会产生错误。

以下应该可以正常工作。

public class Foo:IFoo
{
    public ICollection<IBar> Bars { get; set; }
}

Bar bar1 = new Bar();
Bar bar2 = new Bar();
Bar[] MyBars = { bar1, bar2 };
Foo MyFoo = new Foo();
MyFoo.Bars = MyBars;

【讨论】:

    【解决方案3】:

    按照你的方式,你可以这样做:

    ICollection<Bar> MyBars = new Bar[] {bar1, bar2};
    MyFoo.Bars = MyBars;
    

    您也可以这样做,以编程方式可能更适合您:

    List<Bar> lstBar = new List<Bar>();
    lstBar.Add(bar1);
    lstBar.Add(bar2);
    MyFoo.Bars = lstBar;
    

    全部来源:

    public interface IFoo
    {
        ICollection<IBar> Bars { get; set; }
    }
    public interface IBar
    {
    
    }
    public class Foo : IFoo
    {
        public ICollection<IBar> Bars { get; set; }
    }
    public class Bar : IBar
    {
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            IFoo myFoo = new Foo();
            List<IBar> lstBar = new List<IBar>();
            lstBar.Add(new Bar());
            myFoo.Bars = lstBar;
        }
    }
    

    【讨论】:

      【解决方案4】:

      这种方式是行不通的。看,ICollection&lt;T&gt;T 不协变,因此即使 BarIBarICollection&lt;Bar&gt; 也不是 ICollection&lt;IBar&gt;

      为什么会这样?想象一下,有一些Quux 实现了IBar。如果您可以将ICollection&lt;Bar&gt; 分配给ICollection&lt;IBar&gt;,那么有人可以使用ICollection&lt;IBar&gt;.AddQuux 插入到集合中,因为Quux 也是IBar!但是集合是Bars的集合,所以会破坏类型安全。

      你应该试试

      IBar[] MyBars = {bar1, bar2};
      

      这样您的MyBars 允许插入其他IBars,而不仅仅是Bars。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-07
        • 1970-01-01
        • 2013-11-27
        • 2021-06-29
        • 1970-01-01
        相关资源
        最近更新 更多