在List <type>和List <mytype> </mytype> </mytype>之间进行转换

时间:2010-11-15 20:54:42

标签: c# interface casting

我正在努力解决在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; }
    }
}

3 个答案:

答案 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);

虽然记住虽然对象是相同的,但您将检索不同的列表,因此您需要注意从列表中添加/删除对象。