我正在努力解决在this问题和前两个答案中描述的C#中返回类型协方差的缺乏支持。在大多数情况下,我在设置强制转换时没有任何问题,但是我使用对象/接口列表的一个属性阻碍了我的努力。
为了使IFoo.manyBars
的演员表工作,我需要做些什么?
public interface IBar
{
}
public interface IFoo
{
IBar aBar { get; set; }
IEnumerable<IBar> manyBars { get; set; }
}
class CBar : IBar
{
}
class CFoo : IFoo
{
public CBar aBar { get; set; }
//this cast works
IBar IFoo.aBar
{
get { return aBar; }
set { aBar = (CBar)value; }
}
public List<CBar> manyBars { get; set; }
//the compiler can't cast either of these
List<IBar> IFoo.manyBars
{
get { return (List<IBar>)manyBars; }
set { manyBars = (List<CBar>)value; }
}
}
答案 0 :(得分:3)
试试这个。您必须将using System.Linq;
添加到源文件的顶部,如果它不存在的话。
List<IBar> IFoo.manyBars
{
get { return manyBars.Cast<IBar>().ToList(); }
set { manyBars = value.Cast<CBar>().ToList(); }
}
请注意,这会将每次访问上的新数组分配并复制到该媒体资源。如果这不是您想要的,您应该考虑另一种方法,例如使用类型IEnumerable<IBar>
公开属性。
使用List<IBar>
也意味着有人可能会尝试anObject.manyBars.Remove(0)
对anObject
中存储的列表执行绝对没有,因为会返回副本。
答案 1 :(得分:2)
你可以复制一份:
get { return manyBars.OfType<IBar>().ToList(); }
set { manyBars = value.Cast<CBar>().ToList(); }
但是你无法强制转换那个实例。如果您可以投射该实例,当我尝试Add
不是CBar的IBar时会发生什么。
答案 2 :(得分:0)
根据您的需要,您可以创建一个新的返回列表:
return new List<IBar>(manyBars);
虽然记住虽然对象是相同的,但您将检索不同的列表,因此您需要注意从列表中添加/删除对象。