Activator.CreateInstance 并将装箱对象传递给调用的方法
Activator.CreateInstance and passing a boxed object to an invoked method
我有以下代码...
我的命令处理程序:
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
}
}
我的命令处理程序调度程序:
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
创建我的处理程序 class 的实例并向其传递一个装箱对象(即作为“BaseOperation
”)参数时,.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);
}
如果完整代码在 C# 中,您应该避免 returning dynamic
。 Activator.CreateInstance
是 returning 一个 Object
而不是动态的。
当 properties/methods 不是强类型时,动力学用于脚本语言之间的互操作。
很遗憾您没有描述 IHandler
界面,但是...
我认为;您面临的问题是您的接口定义了您的 class 必须实现 void ExecuteOperation(BaseOperation operation);
这样您的 FindOperationHandler
应该 return 一个 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
}
}
假设您在这里使用 dynamic
来实现双分派,问题是您投错了对象。
需要转换的是 operation
变量(以便将重载决策推迟到运行时),而不是 operationHandler
.
试试这个:
operationHandler.ExecuteOperation(operation as dynamic);
并且您可以避免 FindOperationHandler
上的冗余 dynamic
定义:
private IHandler FindOperationHandler(TBaseProvisioningOperation operation)
{
return Activator.CreateInstance(handlerType, ... args here ...) as IHandler;
}
我有以下代码...
我的命令处理程序:
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
}
}
我的命令处理程序调度程序:
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
创建我的处理程序 class 的实例并向其传递一个装箱对象(即作为“BaseOperation
”)参数时,.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);
}
如果完整代码在 C# 中,您应该避免 returning dynamic
。 Activator.CreateInstance
是 returning 一个 Object
而不是动态的。
当 properties/methods 不是强类型时,动力学用于脚本语言之间的互操作。
很遗憾您没有描述 IHandler
界面,但是...
我认为;您面临的问题是您的接口定义了您的 class 必须实现 void ExecuteOperation(BaseOperation operation);
这样您的 FindOperationHandler
应该 return 一个 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
}
}
假设您在这里使用 dynamic
来实现双分派,问题是您投错了对象。
需要转换的是 operation
变量(以便将重载决策推迟到运行时),而不是 operationHandler
.
试试这个:
operationHandler.ExecuteOperation(operation as dynamic);
并且您可以避免 FindOperationHandler
上的冗余 dynamic
定义:
private IHandler FindOperationHandler(TBaseProvisioningOperation operation)
{
return Activator.CreateInstance(handlerType, ... args here ...) as IHandler;
}