簡體   English   中英

如何動態創建 class 實例並調用實現

[英]How to create the class instances dynamically and call the implementation

我有各種接口,我需要能夠調用它們。 這是基礎 class:

public class MyActorBase<TChild>: ActorBase where TChild : MyActorBase<TChild>
{
    public MyActorBase()
    {
       var actors =  ChildClass
           .GetInterfaces()
           .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IActorMessageHandler<>))
           .Select(x=> (arguments: x.GetGenericArguments(), definition: x))
           .ToImmutableList();

       if (actors.Any())
       {
           var ty = actors.First();
           var obj = Activator.CreateInstance(ty.definition, true);

           // how to call method implementation
       }

    }

    protected sealed override bool Receive(object message) => false;
    private Type ChildClass => ((this as TChild)?? new object()).GetType();
}


public interface IActorMessageHandler<in T>
{
    Task Handle(T msg);
}

我讀了這些博客文章:

  1. 不要使用 Activator.CreateInstance
  2. Linq 表達式
  3. 創建對象的性能影響

作者在編譯時已經知道類型,因此能夠正確轉換。 我在編譯時什么都不知道,所以我不能使用泛型方法或使用 () 運算符或 as 運算符對其進行類型轉換。

更新:我認為人們沒有了解我想要實現的目標。 所以考慮一下。 我做了一個 nuget package 任何人都可以依賴。 在世界的某個地方,有人編寫了以下代碼:

    public class MyMessage
    {
        public int Number { get; }

        public MyMessage(int number) => Number = number;
    }

    public class MyNewActor: MyActorBase<MyNewActor>, IActorMessageHandler<MyMessage>
    {
        public Task Handle(MyMessage msg)
        {
            return Task.CompletedTask;
        }
    }

我希望任何實現 IActorMessageHandler 的class ,我應該能夠調用它的方法Handle(T msg) 因此,雖然我能夠實例化它(考慮到我沒有使用任何依賴注入),但我怎樣才能以最有效的方式調用該方法?

是否有任何替代反射的方法?

使用dynamic關鍵字怎么樣? 這基本上是為您精心包裝的優化反射:

dynamic obj = Activator.CreateInstance(ty.definition, true);
Task t = obj.Handle(msg); //need to define msg before

它繞過編譯時檢查並在運行時推遲方法查找。

請注意,如果無法執行Handle方法的解析,它將在運行時失敗。

這篇博客文章得出結論,由於緩存優化, dynamic最終比反射快得多,因為它經常被調用。

你不應該使用Activator.CreateInstance它非常昂貴。 相反,您可以使用Expression.Lamda以有效的方式創建對象。

  var object =  Expression.Lambda<Func<IActorMessageHandler<TChild>>>(Expression.New(ty.definition.Value.GetConstructor(Type.EmptyTypes) ?? throw new 
    Exception("Failed to create object"))
                        ).Compile()();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM