【问题标题】:How to use reflection to get implementations of a generic interface如何使用反射来实现泛型接口
【发布时间】:2016-04-15 04:04:39
【问题描述】:
  • 我有一个需要读取和密钥方法的通用接口。我想使用反射来获取每个实现的实例。
  • 一旦我有了实现,我想获取它的键并将键和实例存储在字典中。
  • 最终,我将有一个方法传入一个键和字节 [],它会在字典中查找键并使用它检索到的实例来读取字节 [] 并返回一个 object
  • 我希望这是可以理解的,否则我可以在 cmets 中回答问题。
  • 这个例子只有 int 和 string,但在我的实际实现中我会有更多的类型。

目标

拥有一个存储 2 个条目的字典:

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

public interface IRead<T>
{
    T Read(bool[] binary);
    int Key( T type );
}

public class Reader : IRead<int>, IRead<string>
{
    int IRead<int>.Read( byte[] binary )
    {
        // does stuff
        returns 4;
    }

    public int Key( int type ) { return 43; }

    string IRead<string>.Read( byte[] binary )
    {
        // does stuff
        returns "example";
    }

    public int Key( string type ) { return 61; }

    static StreamProcessor( )
    {
        // Here I want to get the definitions
    }
}

【问题讨论】:

  • 您无法根据接口IRead&lt;T&gt; 判断实现将具有无参数构造函数。那么你怎么知道你能够为你找到的每种类型创建一个实例呢?
  • @ScottHannen 我只想将 Reader 转换为字典中定义的类型
  • 看起来您正在寻找某种 IoC 容器实现。查看this 问题和建议的答案。

标签: c# generics reflection interface casting


【解决方案1】:

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

无论如何,这将得到所有实现IRead&lt;&gt;的类型:

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&lt;&gt; 的所有实例。你需要一个实例来给你一把钥匙。

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

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

哪个实例进入字典?

你能得到的最接近的是:

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

【讨论】:

  • #Rob 什么没有编译?如果你不使用它,它可能是 C# 6.0?
【解决方案2】:

我建议将其拆分,因为您正在尝试做一些不同的事情 - 有些是清楚的,有些不是。

首先你要获取实现 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
        );
}

现在您已经有了一堆可以实例化的类型。

从那里开始变得非常模糊。你将如何处理这些类型?将它们放入字典并没有多大用处,因为它们都是不同的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2018-06-28
    相关资源
    最近更新 更多