Мой вопрос как название выше. Например,
но в конце концов он содержит только 1 элемент.
Можем ли мы иметь такой метод, как items.Add(item) ?
Вы не можете, потому что IEnumerable не обязательно представляет коллекцию, в которую можно добавлять элементы. На самом деле, это вовсе не обязательно представляет коллекцию! Например:
Однако вы можете создать новый объект IEnumerable (неопределенного типа), который при перечислении будет предоставлять все элементы старого, а также некоторые ваши собственные. Для этого вы используете Enumerable.Concat :
Это не изменит объект массива (в любом случае вы не можете вставлять элементы в массивы). Но он создаст новый объект, который перечислит все элементы в массиве, а затем "Foo". Кроме того, этот новый объект будет отслеживать изменения в массиве (т.е. всякий раз, когда вы его перечисляете, вы увидите текущие значения элементов).
Тип IEnumerable не поддерживает такие операции. Цель интерфейса IEnumerable — разрешить потребителю просматривать содержимое коллекции. Не изменять значения.
Когда вы выполняете операции типа .ToList(). Add(), вы создаете новый List и добавляете значение в этот список. Он не имеет никакого отношения к исходному списку.
Что вы можете сделать, это использовать метод добавления расширения для создания нового IEnumerable с добавленным значением.
Даже в этом случае он не будет изменять оригинальный объект IEnumerable . Это можно проверить, держа ссылку на нее. Например
После этого набора операций переменная temp по-прежнему будет ссылаться только на перечисляемый с помощью одного элемента "foo" в наборе значений, в то время как элементы будут ссылаться на другой перечислимый со значениями "foo" и "bar".
ИЗМЕНИТЬ
Я постоянно забываю, что Add не является типичным методом расширения на IEnumerable , потому что это один из первых, который я в конечном итоге определяю. Здесь
У меня был список <> моих объектов, но теперь нужно изменить его на IEnumerable <>. Итак, у меня есть это:
Тем не менее, я больше не могу сделать:
Как я должен добавлять элементы сейчас?
8 ответов
Вы можете сделать что-то вроде следующего, используя Concat:
Это в основном создает новый IEnumerable . Трудно сказать, что является лучшим решением в вашем случае, так как недостаточно информации о вашем случае использования.
РЕДАКТИРОВАТЬ: Обратите внимание, что List реализует IEnumerable . Поэтому, если вам нужно передать IEnumerable в качестве параметра, например, вы также можете вместо этого передать List , возможно, сначала вызвав явно AsEnumerable() в вашем списке. Так что, возможно, вы могли бы придерживаться списка вместо IEnumerable.
Краткий ответ: Вы не можете добавлять элементы в IEnumerable
Чуть более длинное объяснение:
IEnumerable — это интерфейс, который заботится исключительно о возможности перечисления / перебора коллекции элементов. Это единственная цель существования IEnumerable . Он абстрагирует любое представление о способе хранения или извлечения перечислимых элементов (это может быть строка символов, список элементов, поток байтов или ряд результатов вычислений), таким образом, если у вас есть интерфейс, который является IEnumerable Вы не можете добавлять элементы к нему, вы можете перебирать только те элементы, которые он предоставляет.
Тем не менее, правильный способ добавить элементы в IEnumerable — это вернуть новый IEnumerable с новыми элементами, добавленными к содержимому оригинала.
Также с библиотеками Linq у вас есть метод расширения, который позволяет преобразовывать ваш IEnumerable в список с помощью IEnumerable.ToList() и вы можете добавлять элементы в список. Это не может быть правильным способом, хотя.
С библиотеками Linq в вашем пространстве имен вы можете сделать следующее:
Вы не можете добавлять элементы в IEnumerable так как у этого интерфейса нет метода Add .
если TransactionSplitLines всегда возвращает экземпляр List
Если вы не можете изменить тип TransactionSplitLines и можете гарантировать, что он всегда возвращает IList
IEnumerable не имеет метода Add(T) . В зависимости от вашего реального типа, вы можете разыграть его так:
Если коллекция, которую вы используете, реализует IList .
Помните, что вы хотите использовать самый простой интерфейс / класс при передаче ваших объектов. Поэтому, если вам нужно использовать методы из IList я бы посоветовал вам использовать их вместо IEnumerable .
Я бы посоветовал вам сделать следующее изменение:
Это зависит от значения и цели вашего свойства TransactionSplitLines .
Если вы хотите разрешить редактирование (добавление / удаление) извне вашего класса, просто сделайте ваше свойство менее универсальным, чем IEnumerable например:
Вместо этого, если вам нужно просто отредактировать коллекцию внутри (я имею в виду в области видимости класса), почему бы вам не сделать что-то вроде этого:
Таким образом, вы можете использовать поле TransactionsSplitLines для внутреннего изменения коллекции.
6 Craig [2011-02-17 11:14:00]
У меня был список моих объектов, но теперь нужно изменить его на IEnumerable . Итак, у меня есть это:
Однако я больше не могу делать:
Как мне теперь добавлять элементы?
8 ответов
19 Решение sloth [2011-02-17 11:23:00]
Вы можете сделать что-то вроде следующего, используя Concat:
Это создает новый IEnumerable . Трудно сказать, какое лучшее решение в вашем случае, поскольку информации о вашем случае использования недостаточно.
EDIT: Обратите внимание, что List реализует IEnumerable . Поэтому, если вам нужно передать IEnumerable в качестве параметра, например, вы также можете передать List , возможно, явно указывая AsEnumerable() в вашем списке. Поэтому, возможно, вы можете придерживаться списка вместо IEnumerable.
Короткий ответ: Вы не можете добавлять элементы в IEnumerable
Немного длиннее объяснение:
IEnumerable — это интерфейс, который исключительно обеспокоен возможностью перечислить/повторить набор элементов. Это единственная цель существования IEnumerable . Он абстрагирует любое представление о способе хранения или извлечения перечислимых элементов (это может быть строка символов, список элементов, поток байтов или серия результатов вычислений), поэтому, если у вас есть интерфейс, который является IEnumerable , вы не можете добавлять к нему элементы, вы можете перебирать только элементы, которые он предоставляет.
Тем не менее, правильный способ добавления элементов в IEnumerable — это вернуть новый IEnumerable с новыми элементами, добавленными к содержимому оригинала.
Также с библиотеками Linq у вас есть метод расширения, который позволяет использовать ваш IEnumerable в List через IEnumerable.ToList() , и вы можете добавлять элементы в список. Это не может быть правильным способом.
С библиотеками Linq в вашем пространстве имен вы можете сделать следующее:
5 Itay Karo [2011-02-17 11:18:00]
Вы не можете добавлять элементы в IEnumerable , так как этот интерфейс не имеет метода Add .
если TransactionSplitLines всегда возвращает экземпляр List
Если вы не можете изменить тип TransactionSplitLines , и вы можете гарантировать, что он всегда возвращает a IList
IEnumerable не имеет метода Add(T) . В зависимости от вашего реального типа вы можете сделать это следующим образом:
Если коллекция, которую вы используете, реализует IList .
Помните, что вы хотите использовать большинство базовых интерфейсов/классов при передаче объектов. Поэтому, если вам нужно использовать методы из IList , я предлагаю вам использовать это вместо IEnumerable .
Я предлагаю вам выполнить следующие изменения:
2 digEmAll [2011-02-17 11:20:00]
Это зависит от значения и цели вашего свойства TransactionSplitLines .
Если вы хотите разрешить редактирование (добавление/удаление) извне вашего класса, просто сделайте свое свойство менее общим, чем IEnumerable , например:
Вместо этого, если вам нужно просто отредактировать коллекцию внутренне (я имею в виду в области класса), почему бы вам не сделать что-то вроде этого:
чтобы вы могли использовать поле TransactionSplitLines , чтобы изменить коллекцию внутри.
2 nawfal [2013-02-17 15:40:00]
Я бы создал этот метод расширения, который делает все это лениво: