C# 如何动态创建类实例并调用实现
我有各种接口,我需要能够调用它们。下面是基类:C# 如何动态创建类实例并调用实现,c#,reflection,activator,C#,Reflection,Activator,我有各种接口,我需要能够调用它们。下面是基类: public class MyActorBase<TChild>: ActorBase where TChild : MyActorBase<TChild> { public MyActorBase() { var actors = ChildClass .GetInterfaces() .Where(i => i.IsGenericType
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);
}
公共类MyActorBase:ActorBase其中TChild:MyActorBase
{
公共MyActorBase()
{
var=ChildClass
.GetInterfaces()
.Where(i=>i.IsGenericType&&i.GetGenericTypeDefinition()==typeof(IActorMessageHandler))
.Select(x=>(参数:x.GetGenericArguments(),定义:x))
.ToImmutableList();
if(actors.Any())
{
var ty=actors.First();
var obj=Activator.CreateInstance(ty.definition,true);
//如何调用方法实现
}
}
受保护的密封覆盖布尔接收(对象消息)=>false;
私有类型ChildClass=>((作为TChild)??新对象()).GetType();
}
公共接口IActorMessageHandler
{
任务句柄(T msg);
}
我读了以下博文:
编写者在编译时已经知道类型,因此能够正确地转换。在编译时我什么都不知道,所以我不能使用泛型方法,也不能使用()运算符或as运算符对其进行类型转换
更新:我认为人们没有意识到我想要实现什么。所以考虑一下这个。我做了一个任何人都能做的nuget包
依赖于。在世界的某个地方,有人编写了以下代码:
公共类MyMessage
{
公共整数{get;}
公共MyMessage(整数)=>number=number;
}
公共类MyNewActor:MyActorBase,IActorMessageHandler
{
公共任务句柄(MyMessage msg)
{
返回Task.CompletedTask;
}
}
我希望实现IActorMessageHandler的任何类都能够调用其方法Handle(tmsg)。因此,虽然我能够实例化它(考虑到我没有使用任何依赖项注入),但如何以最有效的方式调用该方法
除了反射还有其他选择吗?使用
动态关键字怎么样?这基本上是为您精心包装的优化反射:
dynamic obj=Activator.CreateInstance(ty.definition,true);
任务t=对象句柄(msg)//需要定义味精之前
它绕过编译时检查,并在运行时延迟方法查找
请注意,如果无法执行句柄
方法的解析,则在运行时它将失败
得出的结论是,由于缓存优化,dynamic
在频繁调用时比reflection快得多。使用dynamic
关键字怎么样?这基本上是为您精心包装的优化反射:
dynamic obj=Activator.CreateInstance(ty.definition,true);
任务t=对象句柄(msg)//需要定义味精之前
它绕过编译时检查,并在运行时延迟方法查找
请注意,如果无法执行句柄
方法的解析,则在运行时它将失败
得出的结论是,由于缓存优化,dynamic
在相当频繁地调用时比reflection快得多。您不应该使用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()();
var object=Expression.Lambda(Expression.New(ty.definition.Value.GetConstructor(Type.EmptyTypes))抛出新
异常(“未能创建对象”))
).Compile();
您不应该使用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()();
var object=Expression.Lambda(Expression.New(ty.definition.Value.GetConstructor(Type.EmptyTypes))抛出新
异常(“未能创建对象”))
).Compile();
您尝试过什么?您应该能够使用与发现和创建实例相同的反射代码。问题是所有的博客在编译时都知道这个类,所以他们正确地键入它。我的情况不同。我在编译时不知道这个类,所以我不能使用类型转换或者甚至作为操作符来类型转换它。所以你还没有找到这个或者?“我怎样才能以最有效的方式调用这个方法?”-如果你在构造函数中做所有反射和LINQ,坦白说,“高效”已经飞出了窗口。。。您可能希望将actors
移动为静态只读
字段,以便只构建一次?(可能使用typeof(TChild)
或其他东西,而不是将其作为TChild
东西?)另一个选项是使消息处理程序接口非通用。然后就可以直接调用了。你试过什么?您应该能够使用与发现和创建实例相同的反射代码。问题是所有的博客在编译时都知道这个类,所以他们正确地键入它。我的情况不同。我在编译时不知道这个类,所以我不能使用类型转换或者甚至作为操作符来类型转换它。所以你还没有找到这个或者?“我怎样才能以最有效的方式调用这个方法?”-如果你在构造函数中做所有反射和LINQ,坦白说,“高效”已经飞出了窗口。。。您可能希望将actors
移动为静态只读
字段,以便只构建一次?(可能使用typeof(TChild)
或其他东西,而不是将其作为TChild
东西?)另一个选项是使消息处理程序接口非通用。然后可以直接调用它。它比繁琐的MethodInfo和Invoke()快吗?是的,对