繁体   English   中英

获取所有使用特定通用calsses实现类的类

[英]Get all class that implement class with specific generic calsses

我想在我的程序中找到实现给定类的所有类,并将特定调用作为泛型类型。 在下面的例子中,我想找到所有实现MyBaseClass<MyScraper, MyElance>MyBaseClass<MyScraper, MyElance>在这种情况下它是MyProperty而不是OtherProperty因为它实现了其他泛型类。 如何才能做到这一点?

public class MyProperty : MyBaseClass<MyScraper, MyElance>
{
    public override string test()
    {
        var test = base.test();
        test += " + the new";
        return test;
    }
}
public class OtherProperty : MyBaseClass<OtherScraper, OtherElance>
{
    public override string test()
    {
        var test = base.test();
        test += " + the other";
        return test;
    }
}

public class MyBaseClass<S, E>
    where S : IScraper
    where E : IElance
{
    public virtual string test()
    {
        return "base";
    }
}

编辑:找到解决方案,但请告诉我是否有更好的方法

    var test = from x in Assembly.GetAssembly(typeof(Program)).GetTypes()
                                let y = x.BaseType
                                where !x.IsAbstract && !x.IsInterface &&
                                y != null && y.IsGenericType &&
                                y.GetGenericTypeDefinition() == typeof(MyBaseClass<,>) &&
                                y.GenericTypeArguments[0] == typeof(MyScraper) &&
                                y.GenericTypeArguments[1] == typeof(MyElance)
                                select x;

最终解决方案

   var types = AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(a => a.GetTypes())
        .Where(x => !x.IsAbstract && !x.IsInterface)
        .Where(x => x.BaseType != null &&
                    x.BaseType.IsGenericType &&
                    x.BaseType.GetGenericTypeDefinition() == typeof (MyBaseClass<,>) &&
                    x.BaseType.GenericTypeArguments[0] == typeof (MyScraper) &&
                    x.BaseType.GenericTypeArguments[1] == typeof (MyElance))
        .Select(x => x).ToList();

尝试这个:

//var desiredImplementation = typeof (MyBaseClass<>).MakeGenericType(typeof (MyScraper), typeof (MyElance));

var desiredImplementation = typeof (MyBaseClass<MyScraper, MyElance>);

var implementingTypes = Assembly
        .GetExecutingAssembly()
        .GetExportedTypes()
        .Where(type => desiredImplementation.IsAssignableFrom(type))
        .ToList();

您可以更换GetExportedTypes()GetTypes()BindingFlags进一步反思大会也。

装配扫描几乎是最好的方法。

除了你的algorythm,我建议扫描AppDomain而不是特定的程序集 - 这将允许你(或其他人!)更容易扩展你的库...

AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(a => a.GetTypes())
    //...

(免责声明请原谅Linq使用此处,但我厌恶语法linq)

此外,请确保加载任何其他程序集,以确保您在扫描时不会遗漏任何内容。

var searchType = typeof(MyBaseClass<MyScraper, MyElance>);
            var types =
                AppDomain.CurrentDomain.GetAssemblies()
                    // For search only on assemblies where could exsist this types
                    .Where(a => a.GetName().Name == searchType.Assembly.GetName().Name || a.GetReferencedAssemblies().Any(n => n.Name == searchType.Assembly.GetName().Name))
                    .Where(t => !t.IsAbstract && !t.IsInterface)
                    .Select(t => t.GetTypes().Where(a => searchType.IsAssignableFrom(a)))
                    .SelectMany(a => a);

我使用这个版本来搜索所有已加载的程序集,并使用额外的过滤器来处理不能包含我的类型的程序集

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM