Как вы устанавливаете, должен ли метод возвращать IEnumerable<T> или IObservable<T>?
Почему я должен выбрать одну парадигму над другой?
Как вы устанавливаете, должен ли метод возвращать IEnumerable<T> или IObservable<T>?
Почему я должен выбрать одну парадигму над другой?
IEnumerable<T>
T 'sIObservable<T>
T подталкивается к вамПочему я должен выбрать одну парадигму над другой?
Обычно вы не выбираете одну парадигму над другой. Обычно один выделяется естественно как правильный выбор, а другой не имеет никакого смысла.
Рассмотрим следующие примеры:
Огромный текстовый файл CSV имеет элемент в каждой строке, и вы хотите обрабатывать их по одному, не загружая сразу весь файл: IEnumerable<List<string>>
У вас работает веб-сервер HTTP: IObservable<WebRequest>
Вы хотите получить узлы структуры данных дерева в ширину: IEnumerable<Node>
Вы отвечаете на нажатия кнопок пользовательского интерфейса: IObservable<Click>
В каждом из этих примеров (особенно случаев IObservable<T>) просто не имеет смысла использовать другой тип.
IObservable<T> до IEnumerable<T>Если что-то естественно IObservable<T>, но вы хотите обработать его, как если бы это был IEnumerable<T>, вы можете сделать это с помощью этого метода:
IEnumerable<T> Observable.ToEnumerable(this IObservable<T>)
T получает "push" от IObservable<T>, он отправляется в очередь.T из IEnumerable<T>, он блокирует до тех пор, пока очередь не будет пустой, а затем удалит.IEnumerable<T> до IObservable<T>Если что-то естественно IEnumerable<T>, но вы хотите обработать его, как если бы это был IObservable<T>, вы можете сделать это с помощью этого метода:
IObservable<T> Observable.ToObservable(this IEnumerable<T>)
T из IEnumerable<T>.T, он "подталкивает" его к вам через IObservable<T>. IObservable<T> - это специализированный интерфейс, который можно использовать для pub/sub и других других шаблонов. Вы знаете, когда вам нужно вернуть IObservable<T>, поэтому, если нет конкретной необходимости, верните IEnumerable<T>.
Обновить вопрос в комментарии
В принципе, IObservable<> использует механизм "Push", а IEnumerable < > использует механизм "Pull". Если вы собираетесь просто получить список данных, которые не нужно уведомлять подписчиков об изменениях (push), вы можете использовать IEnumerable. Если подписчик (Window, Control, другие клиентские программы/подпрограммы и т.д.) Должен знать, когда данные были изменены, используйте IObservable<>. Одним из примеров является использование IObservable для обновления основного потока пользовательского интерфейса в программе Windows из дочернего потока (обычно это невозможно сделать без фантазийной работы). Читайте об .NET Reactive Extensions (Rx.NET).
Используйте IObservable<T>, если вы хотите поместить данные вызывающим абонентам вашего метода в удобное для вас время. Вы делаете это, вызывая OnNext() on Observers, зарегистрированный интерес через Subscribe().
Используйте IEnumerable<T>, если вы хотите, чтобы вызывающие абоненты вашего метода извлекали данные по своему усмотрению. Они делают это, вызывая GetEnumerator() для получения IEnumerator и вызывая MoveNext() и Current (foreach для компиляции).
UPDATE: возможно, лучше всего привести несколько примеров:
Функция, которая возвращает валютные цены в банке, является хорошим кандидатом для IObservable<T>. Здесь информация имеет критический момент. Как сервер этих данных, вам нужно как можно скорее отправить его клиенту. Клиент не будет знать, когда эти данные будут готовы. Поэтому вы подталкиваете их к ним.
Функция, которая возвращает действительные торговые дни для определенного финансового инструмента и используется для заполнения дней отключения электроэнергии в календарном контроле, является хорошим кандидатом для IEnumerable. Эти данные редко меняются, и клиент (настройка элемента управления) предпочитает потреблять его в темпе, который он диктует.
Используйте IEnumerable<T> для представления списков, используйте IObservable<T> для представления событий. Легкий peasy.