如何反映具有泛型接口的类型,并获得该类型的泛型

时间:2010-02-21 02:59:13

标签: linq generics types

我的第一个目标是基于具有通用的特定接口过滤类型。

我的第二个目标是获取泛型参数本身的类型。

public UserService : IUserService, IDisposable, IExportableAs<IUserService>
{
  ...
}

我不能假设类的结构,它的接口(如果有的话)或类似的。我唯一知道的是我从用于创建此插件的共享程序集中定位ExportableAs<T>。但是,我需要动态注册该类型。

因此,我使用通用接口来标记要导出的类型。在这种情况下,它是IUserService。我这样做假设一些漂亮的Linq查询可以给我我想要的东西。但是,我遇到了一些麻烦。

这是我到目前为止所拥有的:

assembly.GetTypes()
    .Where(t => t.GetInterfaces().Any(i => 
                i.IsGenericType &&
                i.GetGenericTypeDefinition() == typeof(IExportableAs<>))
            ).ToList()
    .ForEach(t => _catalogs.Add(
            new ComposablePart()
            {
                Name = t.FullName,
                Type = t // This is incorrect
            })
        );

这是有效的,但请注意上面的评论“这是不正确的”。此类型是UserService的派生类。

我最终的结果是:

  • 泛型类型会传入IExportableAs<T>(本例中为IUserService
  • 派生类类型(在本例中为UserService

这个问题得到了很好的投票,因为它让我接近(如上所示):How to determine if a type implements a specific generic interface type但是,我需要更进一步找到这种泛型。

随意修改上面的linq。

提前致谢!

1 个答案:

答案 0 :(得分:4)

搞定了

assembly.GetTypes().SelectMany(t => t.GetInterfaces(), (t, i) => new { t, i })
    .Where(ti => ti.i.IsGenericType &&
                 ti.i.GetGenericTypeDefinition() == (typeof(IExportableAs<>)))
    .Select(ti => new ComposablePart() {
        Name = ti.t.FullName,
        Type = ti.i.GetGenericArguments()[0]
    });

[编辑]令我兴奋的是,我没有让我的测试程序运行足够长时间在非通用接口上抛出异常。认为.NET Framework在那里特别聪明。现在更正了代码,我知道它不是。