Учитывая следующий код (который я не знаю, буду компилировать и не правильно):Allow производного типа брошен как родительский тип для возврата `object`, но с помощью метода производного типа в
public abstract class Fetcher {
public abstract IEnumerable<object> Fetch();
}
public class Fetcher<T> : Fetcher {
private readonly Func<IEnumerable<T>> _fetcher;
public Fetcher(Func<IEnumerable<T>> fetcher) { _fetcher = fetcher; }
public IEnumerable<T> Fetch() => _fetcher(); // override or new
}
И это пример установки:
var myFetchers = new List<Fetcher> {
new Fetcher<string>(() => new List<string> { "white", "black" })),
new Fetcher<int>(() => new List<int> { 1, 2 }))
};
Как я могу структурировать свой код, чтобы это сработало?
IEnumerable<IEnumerable<object>> fetcherResults =
myFetchers.Select(fetcher => fetcher.Fetch()); // get objects from derived method
TLDR; Я подумал об этом немного больше. Другой способ сформулировать мой вопрос: каким образом я могу запустить метод Fetch
во всех элементах списка myFetchers
и сохранить коллекцию своих результатов без необходимости определять базовый тип каждого элемента и делать приведение к этому типу, не возвращая IEnumerable<object>
из самого метода Fetch
?
Ключ здесь в том, что в то время, когда объекты другого родового типа находятся в коллекции родительского типа, я хочу запустить метод производного типа, но возвращать результат как IEnumerable<object>
, а не IEnumerable<T>
. (Это может быть сделано с использованием другого метода, если это необходимо, я полагаю, хотя было бы хорошо, если бы это было одно и то же имя.) Это значит, что раздел кода, который не должен знать о сборщиках, может иметь свои данные (и просто нужно пройти fetcherResults
), но часть кода, которая заботится о сборщиках, может полностью игнорировать, с какими типами данных работают личители (а не с их заботой, только потребитель данных должен работать с конкретными типами).
Мне не нужно использовать наследование здесь, и интерфейс IFetcher
будет работать так же хорошо. Я продолжаю думать о том, как явная реализация интерфейса может помочь, но я просто не закрывая петлю прямо сейчас, как сделать эту работу для меня:
// in a class implementing ICollection<T>
public IEnumerator<T> GetEnumerator() => _collection.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable) _collection).GetEnumerator();
Как обычно, реальная ситуация гораздо сложнее, чем это (например, как данные, которые получатели получают из базы данных и т. д.). Но получить эту часть вниз будет все, что мне нужно.
Я рассмотрел следующие ресурсы безрезультатно: implement an inheritable method that returns an object, call method on generic type from abstract parent.
Почему бы не иметь 'IEnumerable FetchGeneric()' и 'IEnumerable
Думаю, меня отбросили, если бы они были с тем же именем. Теперь кажется очевидным, что вы упомянули об этом. Но если бы я решил отложить выборку до тех пор, пока не использовал производный тип, было бы неплохо получить конкретный тип, используя одно и то же имя метода. – ErikE
Я обновил свой вопрос, см. Новый абзац, начинающийся с TLDR; – ErikE