繁体   English   中英

在清单之间投放 <MyType> 和清单 <IMyType>

[英]Cast between List<MyType> and List<IMyType>

我正在尝试解决问题及其前两个答案中所述的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; }
    }
}

尝试这个。 您将不得不using System.Linq;添加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的列表完全 anObject ,因为返回了副本。

您可以复制:

get { return manyBars.OfType<IBar>().ToList(); } 
set { manyBars = value.Cast<CBar>().ToList(); }

但您无法投射该实例。 如果您可以投射该实例,那么当我尝试Add不是CBar的IBar时会发生什么。

根据您的需求,您可以创建一个新列表以返回:

return new List<IBar>(manyBars);

尽管请记住尽管对象相同,但是您将检索不同的列表,因此在添加/删除列表中的对象时需要格外小心。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM