如何使用反射来获得通用接口的实现

时间:2016-04-15 04:04:40

标签: c# generics reflection interface casting

  • 我有一个通用接口,需要读取和密钥方法。我想使用反射来获取每个实现的实例。
  • 一旦我有了实现,我想获得它的密钥并将密钥和实例存储在字典中。
  • 最后,我会有一个方法,我传入一个键和byte [],它会在字典中查找键并使用它检索的实例来读取byte []并返回{{1} }。
  • 我希望这是可以理解的,如果不是,我可以在评论中回答问题。
  • 这个例子只有int和string,但在我的实际实现中我还有更多类型。

目标

要有一个包含2个条目的字典:

  • 43,object
  • 61,IRead<int> new Reader()
IRead<string> new Reader()

2 个答案:

答案 0 :(得分:0)

当您提出问题时,请发布编译的代码。它让每个人的生活更轻松(也许你的答案是因为你写的伪代码是错的?)

无论如何,这将获得实现IRead<>的所有类型:

var types = GetType().Assembly.GetTypes()
.Select(t => new
{
    Type = t,
    MatchingInterfaces = t.GetInterfaces()
                          .Where(i => i.GetGenericTypeDefinition() == typeof(IRead<>))
})
.Where(t => t.MatchingInterfaces.Any())

返回钥匙的先决条件并没有多大意义。您找不到IRead<>的所有实例。你需要一个实例给你一把钥匙。

例如,如果你有这个代码,你的字典会是什么样子:

var readerOne = new Reader();
var readerTwo = new Reader();

哪个实例进入字典?

你最接近的是:

  1. 将方法传递给对象并返回那些实例的密钥
  2. 创建每种类型的虚拟实例以获取密钥
  3. 使密钥方法成为静态,而不是接口的一部分。

答案 1 :(得分:0)

我建议打破这个问题,因为你要做的事情有些不同 - 有些是明确的,有些则不是。

首先,您希望获得实现IReader的类型:

public IEnumerable<Type> GetTypes<TAssignableFrom>()
{
    return this.GetType().Assembly.GetTypes()
        .Where(type => type.IsAssignableFrom(typeof (TAssignableFrom)));
}

你想用这些类型做什么?如果你想创建每种类型的实例,那么他们需要有无参数构造函数或其他相同的构造函数,或者你需要使用一些依赖注入容器。

让我们说他们将拥有无参数构造函数。我们可以将上面的内容更新为

public IEnumerable<Type> GetTypes<TAssignableFrom>()
{
    return this.GetType().Assembly.GetTypes()
        .Where(type => type.IsAssignableFrom(typeof (TAssignableFrom))
            && type.GetConstructor(Type.EmptyTypes) != null
        );
}

现在你有一堆可以实例化的类型。

从那里它变得相当模糊。你会用这些类型做什么?将它们放入字典中并没有多大用处,因为它们都是不同的类型。