c# - 允许派生类型转换为父类型返回 `object` ,但使用派生类型的方法

标签 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
}

这个示例设置:

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> . (我想,如果需要的话,这可以使用不同的方法来完成,尽管如果它是相同的名称会更好。)这样一来,不需要了解 fetcher 的代码部分就可以拥有它的数据(并且只是通过 fetcherResults ),但是代码中关心 fetcher 的部分可以完全忽略 fetcher 使用的数据类型(不是它关心的,只有数据的消费者需要使用特定类型).

我这里不用继承,接口(interface)IFetcher也会工作。我一直在思考显式接口(interface)实现可能有何帮助,但我现在还没有结束循环如何使它对我有用:

// in a class implementing ICollection<T>
public IEnumerator<T> GetEnumerator() => _collection.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable) _collection).GetEnumerator();

和往常一样,实际情况比这更复杂(例如 fetcher 提供的数据来自数据库等)。但我只需要放下这一部分。

我查看了以下资源但无济于事:implement an inheritable method that returns an object , call method on generic type from abstract parent .

最佳答案

正如您所怀疑的那样,有一种直接的方法可以通过显式实现来做到这一点。这仅在您使用接口(interface)而不是抽象类时可用。

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();
}

在此实现中,调用的接口(interface)版本返回IEnumerable<object> ,而类可访问版本返回更具体的 IEnumerable<T> .如果你通过接口(interface)调用fetcher,它会解析到第一个。通过类调用将解析为第二个。

关于c# - 允许派生类型转换为父类型返回 `object` ,但使用派生类型的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38061468/

相关文章:

c# - 如何在 WCF 中为客户端配置 net.tcp 绑定(bind)

java - 将复制任何多维数组的通用函数

c# - XmlReader 连续读取

c# - NuGet 引用存储在哪里?

c# - 在 C# 中合并大文件

javascript - javascript继承之间的区别

php - 改进 PHP 中的类结构而不是使用多重继承

泛型参数的 C# 类型转换

Java 泛型、链表

java - 选择设计模式时的困境