[英]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);
}
我讀了這些博客文章:
作者在編譯時已經知道類型,因此能夠正確轉換。 我在編譯時什么都不知道,所以我不能使用泛型方法或使用 () 運算符或 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.