我有以下代码......
我的命令处理程序:
public class MyHandler : IHandler
{
// I Want to get rid of this method
public override void ExecuteOperation(BaseOperation operation)
{
// This is a work-around
this.ExecuteOperation(operation as SpecificOperation);
}
public override void ExecuteOperation(SpecificOperation operation)
{
// Do actual work here
}
}
My Command handler dispatcher:
private dynamic FindOperationHandler(TBaseProvisioningOperation operation)
{
... some logic here
return Activator.CreateInstance(handlerType, ... args here ...)
}
我的消费者代码
public void PerformProvisioningOperation(BaseOperation operation)
{
// Find the correct handler for this operation
var operationHandler = this.FindOperationHandler(operation as TBaseProvisioningOperation);
// make it execute the operation
// NOTE: 'operation' is SpecificOperation type, for example
operationHandler.ExecuteOperation(operation); // <--- problem is here
}
问题在于,当我使用Activator.CreateInstance
创建处理程序类的实例并将其传递给一个盒装对象(即&#34; BaseOperation
&#34;)参数时,.NET在处理程序中查找一个方法,该方法具有基类型的参数,而不是自动调用可以处理该对象的方法(如果它是未装箱的(即显式转换))。
当然我们有SpecificOperation : BaseOperation
换句话说:我想在执行operationHandler.ExecuteOperation(operation);
时,.NET调用ExecuteOperation(SpecificOperation operation)
而不是ExecuteOperation(BaseOperation operation)
,因为操作参数是盒装的(即它是SpecificOperation
但被低估为BaseOperation
)。
我如何实现这一目标?
编辑:
public interface IHandler<TOperation> where TOperation : BaseOperation
{
/// <summary>
/// TODO: Get rid of this method
/// </summary>
/// <param name="operation">The operation to execute - boxed</param>
void ExecuteOperation(BaseOperation operation);
/// <summary>
/// Executes the operation
/// </summary>
/// <param name="operation">The operation to execute - unboxed</param>
void ExecuteOperation(TOperation operation);
}
答案 0 :(得分:1)
假设您在此处使用dynamic
来实现Double-Dispatch,问题是您正在施放错误的对象。
需要进行转换的operation
变量(为了将重载解析推迟到运行时),而不是operationHandler
。
请改为尝试:
operationHandler.ExecuteOperation(operation as dynamic);
您可以避免dynamic
上的冗余FindOperationHandler
定义:
private IHandler FindOperationHandler(TBaseProvisioningOperation operation)
{
return Activator.CreateInstance(handlerType, ... args here ...) as IHandler;
}
答案 1 :(得分:0)
如果完整代码在C#中,则应避免返回dynamic
。 Activator.CreateInstance
正在返回Object
而不是动态。
当属性/方法没有强大的类型时,动态是用于脚本语言之间的互操作。
太糟糕了,你没有描述IHandler
界面,但......
我想;您面临的问题是您的界面定义了您的班级必须实施void ExecuteOperation(BaseOperation operation);
这样您的FindOperationHandler
应该返回IHandler
。
private IHandler FindOperationHandler(TBaseProvisioningOperation operation)
{
... some logic here
return (IHandler)Activator.CreateInstance(handlerType, ... args here ...)
}
对于你的经纪人:
public class MyHandler : IHandler
{
public override void ExecuteOperation(BaseOperation operation)
{
var operation = (SpecificOperation)operation;
// Do actual work here
}
}