如何获取类列表,从一个类和一个接口继承/或从两个接口继承

我想创建基类的默认后代实例的列表。我已经可以获得的是那些后代的一个List<Type>或IEnumerable<Type>多个。


基类和后代都是自制的。所以我非常理解他们。


C# 框架是否已经为此提供了一种智能方法?


这就是我得到的:


    public static List<Type> GetList_Descendants(Type baseClassType, string assemblyName)

    {

        return Assembly

        .GetAssembly(baseClassType)

        .GetTypes()

        .Where(t => t.IsSubclassOf(baseClassType))

        .ToList(); // Otherwise return would be of type IEnumerable.

    }


    public static void Add_AllDescendants<T>(this List<T> emptySource, List<Type> descendants)

        where T : new()

    {

        emptySource.AddRange(???);

    }

类的后代 && 接口

stop-cran已经给了我一个答案,关于如何获取泛型类型给出的类的后代。(请参阅下面的第一个答案和前两个评论。)


两个接口的后代

我怎样才能获得两个接口的后代?这就是我所做的,它的工作原理:


    /// <summary>

    /// Assumes, that there are two interfaces and classes inheriting of both - all placed in the same assembly.

    /// 1st interface is IStrategy. 2nd interface is described by generic type.

    /// 

    /// Creates an IEnumerable of all available Func'IStrategy' child instances which are of generic type, too.

    /// Thus one decouple creation of such a IEnumerable from creating the child classes of type IStrategy.

    /// </summary>

    /// <typeparam name="T"></typeparam>

    /// <returns></returns>

    public static IEnumerable<Func<IStrategy>> GetByInterfaceBaseType<T>() =>

    typeof(T)

    .Module

    .Assembly

    .GetTypes()

    .Where(t => (t.GetInterface(typeof(T).FullName)!= null)

             && (t.GetInterface(nameof(IStrategy)) != null))

    // We assume T has a parameterless constructor

    .Select(t => (Func<IStrategy>)(() => (IStrategy)Activator.CreateInstance(t)));


对我来说,这个案子已经解决了。但好的建议总是受欢迎的!


守着星空守着你
浏览 103回答 1
1回答

手掌心

考虑到问题评论,我建议有一个IStrategy接口并用于IEnumerable<Func<IStrategy>>注入策略工厂列表(这里为了简洁起见我使用委托工厂,可以使用接口代替)。因此,我们可以将创建这样一个列表与创建策略脱钩:static IEnumerable<IStrategy> CreateAll(this IEnumerable<Func<IStrategy>> factories) =>&nbsp; &nbsp; factories.Select(factory => factory());使用示例:listOfStrategies.AddRange(&nbsp; &nbsp; new Func<IStrategy>[]&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; () => new B(),&nbsp; &nbsp; &nbsp; &nbsp; () => new C()&nbsp; &nbsp; }).CreateAll()); // 2 items (`B` and `C`) will be added.Func<IStrategy>如果方便的话,可以从类层次结构中创建策略工厂列表 ( ):static IEnumerable<Func<IStrategy>> GetByBaseType<T>() =>&nbsp; &nbsp; typeof(T)&nbsp; &nbsp; &nbsp; &nbsp; .Assembly&nbsp; &nbsp; &nbsp; &nbsp; .GetTypes()&nbsp; &nbsp; &nbsp; &nbsp; .Where(t => t.IsSubclassOf(typeof(T)) && t.GetInterface(nameof(IStrategy)) != null)&nbsp; &nbsp; &nbsp; &nbsp; // We assume t has a parameterless constructor&nbsp; &nbsp; &nbsp; &nbsp; .Select(t => (Func<IStrategy>)(() => (IStrategy)Activator.CreateInstance(t)));一个样品:class A { }class B : A, IStrategy { }class C : A, IStrategy { }创建策略工厂列表:var factories = GetByBaseType<A>().ToList(); // Two `Func<IStrategy>` objectsvar strategies = CreateAll(factories).ToList(); // Two `IStrategy` objects - `B` and `C`.此外,通常返回的方法比接受并向其中添加项目的IEnumerable<T>方法更具可重用性和“纯粹”性。List<T>还有一件事 - 许多 DI 容器支持解析所有已注册实现的列表。请参阅UnityContainer下面的示例:var c = new UnityContainer()&nbsp; &nbsp; .RegisterType<IStrategy, B>("B")&nbsp; &nbsp; .RegisterType<IStrategy, C>("C");// Two items - `B` and `C`.c.Resolve<IEnumerable<IStrategy>>().ToList();
打开App,查看更多内容
随时随地看视频慕课网APP