Как реализовать сложный IEnumerable <T>непосредственно внутри типа, содержащего свойство IEnumerable <T>? - PullRequest
0 голосов
/ 14 января 2011

У меня есть общая реализация коллекции для различных вещей, которые внутри:

public class ImageDocument

с такими свойствами, как:

.Objects
.Effects
.Layers

каждый из которых в основном IEnumerable<T>, но у меня также есть отдельные вызовы, которые дают мне счетчик для каждого из них, что-то вроде:

GetNumObjects()
GetNumEffects()
GetNumLayers()

но это члены более низкого уровня, которые я хочу обернуть, а также реализовать вышеуказанные свойства (.Objects, .Effects, .Layers) как IEnumerable<T>, также используя элементы более низкого уровня, такие как:

GetObject (int index)
GetEffect (int index)
GetLayer (int index)

У меня есть собственный IEnumerable<T> подобный интерфейс, который наследуется от IEnumerable<T>.

В конце я хочу, чтобы эти свойства были такими:

ICountableEnumerable Objects
ICountableEnumerable Effects
ICountableEnumerable Layers

чтобы я мог их перечислять, получать доступ к их счетам (используя низкоуровневые функции), а также иметь возможность их индексировать:

myImageDocument.Objects.Count, etc.
myImageDocument.Objects[4]
foreach ... myImageDocument.Objects ...

Могу ли я реализовать их напрямую, как реализацию IEnumerable<T> внутри ImageDocument, например:

   public IEnumerator<Objects> GetEnumerator()
   {
      foreach(...)
      {
         yield return obj;
      }
   }

или мне нужен промежуточный тип для каждого из этих свойств? Что-то вроде:

ObjectCollection
EffectCollection
LayerCollection

который реализует ICountableEnumerable?

Ответы [ 3 ]

4 голосов
/ 14 января 2011

Я бы, наверное, сделал что-то вроде:

class ImageDocument
{
    public ReadOnlyCollection<Effect> Effects { get { ... } }
    public ReadOnlyCollection<Layer> Layers { get { ... } }
    ...

Таким образом, пользователь может использовать все приятные свойства ReadOnlyCollection, такие как count и т. Д. Коллекция только для чтения - это оболочка вокруг изменяемой коллекции; вы можете сохранить логику изменчивой коллекции в качестве детали реализации и просто предоставить оболочку, доступную только для чтения.

2 голосов
/ 14 января 2011

Что если в вашем классе вы держали коллекции как List ? Тогда ваш IEnumerable .Objects и другие могут вернуть список, который был бы перечисляемым и оптимизированным для индекса и подсчета с помощью LINQ.

1 голос
/ 07 декабря 2011

Я бы предложил объявить тип структуры для каждого из различных стилей перечисления;структура должна содержать неизменную ссылку на базовую коллекцию и реализовывать IEnumerable и публично предоставлять метод GetEnumerator, который, в свою очередь, вызовет baseThing.GetLayersEnumerator () или какую-либо другую подобную функцию.Такой подход позволил бы избежать упаковки во многих распространенных сценариях использования и - в отличие от структур, возвращаемых такими вещами, как List.GetEnumerator, - демонстрировал бы семантику ссылок независимо от того, был ли он упакован.

...