简体   繁体   中英

Cast between List<MyType> and List<IMyType>

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'm 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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