亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何獲取類列表,從一個類和一個接口繼承/或從兩個接口繼承

如何獲取類列表,從一個類和一個接口繼承/或從兩個接口繼承

C#
守著星空守著你 2023-07-09 17:53:44
我想創建基類的默認后代實例的列表。我已經可以獲得的是那些后代的一個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)));對我來說,這個案子已經解決了。但好的建議總是受歡迎的!
查看完整描述

1 回答

?
手掌心

TA貢獻1942條經驗 獲得超3個贊

考慮到問題評論,我建議有一個IStrategy接口并用于IEnumerable<Func<IStrategy>>注入策略工廠列表(這里為了簡潔起見我使用委托工廠,可以使用接口代替)。因此,我們可以將創建這樣一個列表與創建策略脫鉤:


static IEnumerable<IStrategy> CreateAll(this IEnumerable<Func<IStrategy>> factories) =>

    factories.Select(factory => factory());

使用示例:


listOfStrategies.AddRange(

    new Func<IStrategy>[]

    {

        () => new B(),

        () => new C()

    }).CreateAll()); // 2 items (`B` and `C`) will be added.

Func<IStrategy>如果方便的話,可以從類層次結構中創建策略工廠列表 ( ):


static IEnumerable<Func<IStrategy>> GetByBaseType<T>() =>

    typeof(T)

        .Assembly

        .GetTypes()

        .Where(t => t.IsSubclassOf(typeof(T)) && t.GetInterface(nameof(IStrategy)) != null)

        // We assume t has a parameterless constructor

        .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>` objects

var strategies = CreateAll(factories).ToList(); // Two `IStrategy` objects - `B` and `C`.

此外,通常返回的方法比接受并向其中添加項目的IEnumerable<T>方法更具可重用性和“純粹”性。List<T>


還有一件事 - 許多 DI 容器支持解析所有已注冊實現的列表。請參閱UnityContainer下面的示例:


var c = new UnityContainer()

    .RegisterType<IStrategy, B>("B")

    .RegisterType<IStrategy, C>("C");


// Two items - `B` and `C`.

c.Resolve<IEnumerable<IStrategy>>().ToList();


查看完整回答
反對 回復 2023-07-09
  • 1 回答
  • 0 關注
  • 130 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號