我正在尝试将头缠绕在界面上。我一直在强加这样的东西:
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>.
我对如何正确执行此操作完全不知所措。填充接口集合的正确方法是什么?
编辑:我实现的方式可能是问题的一部分。
public class Foo : IFoo
{
public ICollection<IBar> Bars { get; set; }
}
问题是Foo
类,应该是:
public class Foo : IFoo
{
public ICollection<Bar> Bars { get; set; }
}
或如果要使用ICollection<IBar>
:
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<Bar>
转换为ICollection<IBar>
。
您如何在此处实现栏属性很重要。您无法将混凝土类型分配给接口类型。当您尝试进行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;
为您的方式,您可以这样做:
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;
}
}
它不会以这种方式工作。参见,ICollection<T>
在T
上不是协变量,因此,即使Bar
是IBar
,ICollection<Bar>
也不是ICollection<IBar>
。
为什么这样?想象一下,有一些Quux
实施IBar
。如果您可以将ICollection<Bar>
分配给ICollection<IBar>
,则可以使用ICollection<IBar>.Add
将Quux
插入集合中,因为Quux
也是IBar
!但是该集合是Bar
s的集合,因此类型的安全性将被打破。
您应该尝试
IBar[] MyBars = {bar1, bar2};
这样,您的MyBars
允许插入其他IBar
s,而不仅仅是Bar
s。