如何动态创建 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:

  1. Dont use Activator.CreateInstance
  2. Linq Expressions
  3. Creating objects performance implications

编写者在编译时已经知道类型,因此能够正确转换。我在编译时什么都不知道,所以我不能使用通用方法或使用 () 运算符或 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()();