Возврат IEnumerable <IMyInterface>из списка <MyInterfaceClass> - PullRequest
0 голосов
/ 06 января 2012

РЕДАКТИРОВАТЬ : Этот вопрос был бы недействительным в .NET 4, поскольку он на самом деле работает как нужно.

У меня есть класс данных, который должен реализовывать такой интерфейс:

public interface IData
{
   IEnumberable<IOther> OtherList { get; }
   IOther AddOther();
   void RemoveOtherData(IOther data);
}

Но я застрял с объявлением фактического члена в Data

public class Data : IData
{
   // desired, always return the same reference
   public IEnumberable<IOther> OtherList { get { return _mOtherList } }
   // Non persistent reference not desirable.
   public IEnumerable<IOther> OtherList { get { return _mOtherList.Select(x => x as IOther); } }        
   List<IOther> _mOtherList = new List<Other>(); // error, type mismatch
   List<Other> _mOtherList = new List<Other>(); // error, property return type mismatch
   IEnumerable<IOther> _mOtherList = new List<Other>(); // ok, but cannot use List methods without casting.
}

Каково было бы лучшее решение в этом случае?

Ответы [ 3 ]

2 голосов
/ 06 января 2012
public class Data : IData
{
   public IEnumerable<IOther> OtherList { get; private set; }        
   List<Other> _mOtherList = new List<Other>();

   public Data()
   {
     OtherList=mOtherList.Cast<IOther>();
   }
}

Вкл .net 4 IEnumerable<out T> является ко-вариантом.то есть класс, который реализует IEnumerable<Other>, автоматически также реализует IEnumerable<IOther>.Так же можно просто написать:

public class Data : IData
{
   public IEnumerable<IOther> OtherList { get{return mOtherList;} }        
   List<Other> _mOtherList = new List<Other>();
}

Но я бы этого не допустил, поскольку он нарушает инкапсуляцию и позволяет посторонним изменять ваш список.

((List<Other>)MyData.OtherList).Add(...);
1 голос
/ 06 января 2012

Другой класс должен реализовывать интерфейс IOther, и вам не нужно приводить.

Когда вы объявляете _mOtherList, это IEnumerable, поэтому вы не можете использовать методы списка. Объявите это как список.

public class Data : IData
{
   List<IOther> _mOtherList = new List<Other>();

   public IEnumberable<IOther> OtherList { get { return _mOtherList } }

   IOther AddOther()
   {
       return null;
   }
   void RemoveOtherData(IOther data){}
}

Ваш другой класс:

class Other : IOther
{
   //some members
}
0 голосов
/ 06 января 2012

Поскольку IEnumerable является ковариантным, это нормально:

    public interface IInterface{}

    public class ClassA : IInterface{}

    public class ClassB
    {
        private readonly List<ClassA> _classAs;

        public IEnumerable<IInterface> Data{ get { return _classAs; } }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...