Приведение между списком <MyType>и списком <IMyType> - PullRequest
2 голосов
/ 15 ноября 2010

Я пытаюсь обойти отсутствие поддержки ковариации возвращаемого типа в 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 ]

3 голосов
/ 15 ноября 2010

Попробуй это.Вам нужно будет добавить 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, поскольку копия возвращается.

2 голосов
/ 15 ноября 2010

Вы можете сделать копию:

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

, но вы не можете разыграть этот экземпляр.Если бы вы могли разыграть этот экземпляр, что произойдет, когда я попытаюсь Add IBar, который не является CBar.

0 голосов
/ 15 ноября 2010

В зависимости от ваших потребностей, вы можете создать новый список для возврата:

return new List<IBar>(manyBars);

Хотя помните, что, хотя объекты будут одинаковыми, вы будете получать другой список, поэтому вам нужно быть осторожным при добавлении / удалении объектов из списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...