C# 双重协方差
我有C# 双重协方差,c#,covariance,C#,Covariance,我有 公共接口IFoo { IEnumerable Thingies{get;} } 我想这样做 public interface IFoo { IEnumerable<IThingy> Thingies{get;} } class Thing1:i Thingy { ... } 类实现foo:IFoo { 列出你的事情; IEnumerable Thingies{get{return m_things;}} } Thingies返回thing1的IList(它是IEnu
公共接口IFoo
{
IEnumerable Thingies{get;}
}
我想这样做
public interface IFoo
{
IEnumerable<IThingy> Thingies{get;}
}
class Thing1:i Thingy
{
...
}
类实现foo:IFoo
{
列出你的事情;
IEnumerable Thingies{get{return m_things;}}
}
Thingies返回thing1的IList(它是IEnumerable)(它是i字符串)。因此,理论上,这段代码应该有效,但事实并非如此。VS建议在getter中加入一个角色;可编译但在运行时失败的。我是否对c#4的协方差期望过高
VS2010->Silverlight 4。下面是编译错误
无法将类型“System.Collections.Generic.List
”隐式转换为“System.Collections.Generic.IEnumerable
”。存在显式转换(是否缺少强制转换?)
编辑:人们告诉我这应该行得通,但在SL4中行不通。你可以使用:
类实现foo:IFoo
{
列出你的事情;
数不清的东西
{
得到
{
返回m_things.Cast();
}
}
}
这是因为IEnumerable
没有隐式实现IEnumerable
这在C#/.NET4中工作得很好。这是一个完整的编译和工作示例:
class ImplementFoo : IFoo
{
List<Thing1> m_things;
IEnumerable<IThingy> Thingies
{
get
{
return m_things.Cast<IThingy>();
}
}
}
名称空间测试
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;
公共接口i ingy{}
公共接口IFoo
{
IEnumerable Thingies{get;}
}
内部类Thing1:i thingy{}
内部类ImplementFoo:IFoo
{
私有列表m_things=new List(){new Thing1()};
公共数字事物
{
获取{return m_things;}
}
}
内部课程计划
{
私有静态void Main(字符串[]args)
{
var impl=new ImplementFoo();
Console.WriteLine(impl.Thingies.Count());
Console.WriteLine(“按任意键退出”);
Console.ReadKey();
}
}
}
我怀疑问题在于您的目标是.NET3.5sp1或更早版本,而不是.NET4.0。协方差只有在针对.NET4时才能正常工作,因为它需要更改新的框架。在这种情况下,.NET4中的IEnumerable实际上是,这是工作所必需的。这是SL4和CLR4之间的区别。IEnumerable接口未标记为“out”。显然是在SL5中修复的Hmmm,看看Reed的答案,然后也许我在这里给出了一个.NET 4之前的答案…这在.NET 4中确实有效。看:很好!我没有注意到这个新功能,我已经习惯于在演员名单上打电话。。。您的项目是否以.NET 4为目标?.NET 4是肯定的。让我再试一次。实际上Silverlight 4这解释了为什么它对我不起作用,我用
ICollection
和Collection
进行测试。似乎ICollection不是out T
@Anthony:ICollection
具有将T作为输入的方法。如果你有一组香蕉,你可以把它当作一组水果,然后你可以把一个桔子放进一组香蕉里。这不应该是合法的,所以收集接口在t中不允许是协变的。@Anthony Sottile是的,这是正确的。ICollection不是4.0中的co/contra变体接口之一。@Eric现在有了意义。我想我应该考虑一下作为一个可编辑集合的含义,现在我的评论听起来很愚蠢:P@Anthony:不用担心;这些东西很难让你的大脑运转起来!
class ImplementFoo : IFoo
{
List<Thing1> m_things;
IEnumerable<IThingy> Thingies
{
get
{
return m_things.Cast<IThingy>();
}
}
}
namespace Test
{
using System;
using System.Collections.Generic;
using System.Linq;
public interface IThingy { }
public interface IFoo
{
IEnumerable<IThingy> Thingies { get; }
}
internal class Thing1 : IThingy { }
internal class ImplementFoo : IFoo
{
private List<Thing1> m_things = new List<Thing1>() { new Thing1() };
public IEnumerable<IThingy> Thingies
{
get { return m_things; }
}
}
internal class Program
{
private static void Main(string[] args)
{
var impl = new ImplementFoo();
Console.WriteLine(impl.Thingies.Count());
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}