Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取类列表,从一个类和一个接口继承/或从两个接口继承_C#_.net_Extension Methods_C# 7.3 - Fatal编程技术网

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

C# 如何获取类列表,从一个类和一个接口继承/或从两个接口继承,c#,.net,extension-methods,c#-7.3,C#,.net,Extension Methods,C# 7.3,我想创建基类的默认子体实例列表。我已经可以得到这些后代的列表或IEnumerable 基类和后代是自制的。所以我非常了解他们 C框架是否已经为此提供了一种智能方法 这就是我得到的: public static List<Type> GetList_Descendants(Type baseClassType, string assemblyName) { return Assembly .GetAssembly(baseClassTyp

我想创建基类的默认子体实例列表。我已经可以得到这些后代的列表或IEnumerable

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

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)));
这里有一个链接,您可能也会感兴趣:


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

考虑到问题的评论,我建议使用一个IStrategy接口,并使用IEnumerable来注入策略工厂列表。这里,为了简洁起见,我使用代理工厂,可以使用接口。因此,可以将创建此类列表与创建策略分离:

static IEnumerable<IStrategy> CreateAll(this IEnumerable<Func<IStrategy>> factories) =>
    factories.Select(factory => factory());
创建策略工厂列表:

var factories = GetByBaseType<A>().ToList(); // Two `Func<IStrategy>` objects
var strategies = CreateAll(factories).ToList(); // Two `IStrategy` objects - `B` and `C`.

考虑到问题的评论,我建议使用一个IStrategy接口,并使用IEnumerable来注入策略工厂列表。这里,为了简洁起见,我使用代理工厂,可以使用接口。因此,可以将创建此类列表与创建策略分离:

static IEnumerable<IStrategy> CreateAll(this IEnumerable<Func<IStrategy>> factories) =>
    factories.Select(factory => factory());
创建策略工厂列表:

var factories = GetByBaseType<A>().ToList(); // Two `Func<IStrategy>` objects
var strategies = CreateAll(factories).ToList(); // Two `IStrategy` objects - `B` and `C`.

这里的问题是,即使对基类型施加where T:new约束,也不能保证其所有后代都遵循该约束,即具有无参数构造函数。你想达到什么目标?一般来说,依赖继承接口使用依赖注入比依赖类层次结构更方便。我想创建某种工厂,遍历与基类相关的所有策略。所有子代都将有一个无参数构造函数。这里的问题是,即使对基类型施加where T:new约束,也不能保证其所有子代都遵循它,即有一个无参数构造函数。你想达到什么目标?一般来说,依赖继承接口使用依赖注入比依赖类层次结构更方便。我想创建某种工厂,遍历与基类相关的所有策略。所有子代都将有一个无参数构造函数。
var factories = GetByBaseType<A>().ToList(); // Two `Func<IStrategy>` objects
var strategies = CreateAll(factories).ToList(); // Two `IStrategy` objects - `B` and `C`.
var c = new UnityContainer()
    .RegisterType<IStrategy, B>("B")
    .RegisterType<IStrategy, C>("C");

// Two items - `B` and `C`.
c.Resolve<IEnumerable<IStrategy>>().ToList();