开发者

Cast between List<MyType> and List<IMyType>

开发者 https://www.devze.com 2023-01-25 19:36 出处:网络
I\'m trying to work around the lack of support for return type covariance in C# as described in this question and the first two answers to it.For the most part I\'m not having any problems setting up

I'm trying to work around the lack of support for return type covariance in C# as described in this question and the first two answers to it. For the most part I'm not having any problems setting up the casts, but one property where I'开发者_如何学Gom using a list of objects/interfaces is stymieing my efforts.

What do I need to do in order to make the casts for IFoo.manyBars work?

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; }
    }
}


Try this. You will have to add using System.Linq; to the top of the source file, if it's not there already.

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

Note that this will allocate and copy a new array on each access to the property. If this is not what you want, you should consider an alternative approach, such as exposing the property using the type IEnumerable<IBar>.

Using List<IBar> also means someone might try to do anObject.manyBars.Remove(0) which will do absolutely nothing to the list stored in anObject, since a copy is returned.


You can make a copy:

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

but you can't cast that instance. If you could cast that instance, what happens when I try to Add an IBar that is not a CBar.


Depending on your needs, you could create a new list for returning:

return new List<IBar>(manyBars);

Although remember that although the objects will be the same, you will be retrieving a different list, so you'll need to be careful about adding/removing objects from the list.

0

精彩评论

暂无评论...
验证码 换一张
取 消