Eri*_*ikE 6 c# generics inheritance
鉴于以下代码(我知道不会编译并且不正确):
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
}
Run Code Online (Sandbox Code Playgroud)
这个示例设置:
var myFetchers = new List<Fetcher> {
new Fetcher<string>(() => new List<string> { "white", "black" })),
new Fetcher<int>(() => new List<int> { 1, 2 }))
};
Run Code Online (Sandbox Code Playgroud)
如何构建我的代码以便这可以工作?
IEnumerable<IEnumerable<object>> fetcherResults =
myFetchers.Select(fetcher => fetcher.Fetch()); // get objects from derived method
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)
像往常一样,真实情况比这更复杂(例如,提取者提供的数据来自数据库等).但是让这一部分失效将是我所需要的.
我已经看过以下资源无济于事:实现返回一个对象可继承的方法,从抽象父泛型类型调用方法.
正如您所怀疑的那样,有一种直接的方法可以通过显式实现来做到这一点。仅当您使用接口而不是抽象类时,这才可用。
public interface IFetcher {
IEnumerable<object> Fetch();
}
public class Fetcher<T> : IFetcher {
private readonly Func<IEnumerable<T>> _fetcher;
public Fetcher(Func<IEnumerable<T>> fetcher) { _fetcher = fetcher; }
IEnumerable<object> IFetcher.Fetch() => Fetch().Cast<object>();
public IEnumerable<T> Fetch() => _fetcher();
}
Run Code Online (Sandbox Code Playgroud)
在此实现中,调用的接口版本返回IEnumerable<object>,而类可访问版本返回更具体的IEnumerable<T>。如果您通过接口调用获取器,它将解析为第一个。通过类调用将解决第二个问题。
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |