Список IEnumerable через цепочку переопределения
Хорошо, трудно сформулировать точный заголовок для этого вопроса, но здесь идет... У меня есть абстрактный класс Block, который выглядит примерно так:
public abstract class Block
{
public bool Enabled{get; private set;}
public virtual IEnumerable<KeyValuePair<string, string>> GetDefaultUsages()
{
yield return new KeyValuePair<string, string>("Enabled", "true");
}
}
И скажу, что у меня есть подкласс:
public class Form : Block
{
public string Key{get; private set;}
public override IEnumerable<KeyValuePair<string, string>> GetDefaultUsages()
{
yield return new KeyValuePair<string,string>("Key", string.Empty);
// can't do: yield return base.GetDefaultUsages()
}
}
Идея заключается в том, что GetDefaultUsages() всегда будет возвращать IEnumerable, содержащий все строки, пары строк, которые были определены через всю цепочку наследования. Сначала я надеялся, что ключевое слово yield поддержит утверждение вроде:
yield return (some IEnumerable<T> object);
Но, видимо, это не сработает. Я понимаю, что могу сделать:
foreach(KeyValuePair<string, string> kv in base.GetDefaultUsages())
{
yield return kv;
}
Но я надеялся на несколько более чистый синтаксис (и избегая создания ненужных промежуточных IEnumerators).
У любого есть идеи хорошего способа реализовать это.
Ответы
Ответ 1
Вам нужно сделать что-то вроде метода foreach, потому что base.GetDefaultUsages()
возвращает IEnumerable. yield return
имеет дело с отдельными элементами, а не с коллекциями. Хотя было бы неплохо, если бы yield return
мог возвращать коллекцию объекта.
2 недели назад Джон Оксли задал аналогичный вопрос.
Edit:
Похоже, что Барт Джейкобс, Эрик Мейер, Фрэнк Пьенсенс и Вольфрам Шульте уже писали очень интересную статью о том, что они называют вложенными итераторами, что в основном о чем вы просите.