如何动态创建 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);
}
我阅读了这些博客 post:
编写者在编译时已经知道类型,因此能够正确转换。我在编译时什么都不知道,所以我不能使用通用方法或使用 () 运算符或 as 运算符对其进行类型转换。
UPDATE: I think people are not getting the idea of what I want to achieve. so consider this. I made a nuget package which anyone can
depend upon. Somewhere in the world, someone writes this code:
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
方法的解析,它将在 运行 时失败。
This blog post 得出结论,由于缓存优化,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()();
我有各种接口,我需要能够调用它们。这是基础 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);
}
我阅读了这些博客 post:
编写者在编译时已经知道类型,因此能够正确转换。我在编译时什么都不知道,所以我不能使用通用方法或使用 () 运算符或 as 运算符对其进行类型转换。
UPDATE: I think people are not getting the idea of what I want to achieve. so consider this. I made a nuget package which anyone can depend upon. Somewhere in the world, someone writes this code:
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
方法的解析,它将在 运行 时失败。
This blog post 得出结论,由于缓存优化,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()();