我在基类中有一个受保护的方法,它接受一个Func< T>然后转身并执行一些额外的好处。用法示例:
public MyResponse DoSomething(MyRequest request)
{
return base.Execute(() => this.Channel.DoSomething(request));
}
我要做的是获取func委托实例并将表达式中的方法调用重定向到this.Channel之外的另一个实例,如下所示:
protected TResponse Execute<TResponse>(Func<TResponse> command)
{
return command.Method.Invoke(this.otherInstanceOfChannel, command.Target);
}
这里的“this.otherInstanceOfChannel”将是与原始调用中传递的“this.channel”不同的具体类的实例,但实现相同的接口。我只需要找出正在调用的方法,并在另一个从调用者传入原始参数的实例上执行该方法。我开始沿着MethodCallExpressions之类的路径开始,但我的表达式foo很弱......
为了清晰而编辑/重写 - 希望这个版本更有意义。
谢谢, 马特
答案 0 :(得分:1)
我相信你可以像这样提供lambda表达式中的实例:
IMyChannel myChannelInstance = MyChannelInstanceFactory.Create();
Execute(() => myChannelInstance.DoSomething(request))
如果使用lambda表达式无法做到这一点,我相信他们可以将其更改为委托,它可以正常工作。 lambda表达式指向一个代码执行块,因此您可以在该代码块中放置与表达式参数匹配的任何内容。
答案 1 :(得分:1)
是的,你可以这样做。现在没时间给你完整的解决方案,但这是你要做的事情的骨架:
protected TResponse Execute<TResponse>(Expression<Func<TResponse>> command)
{
// Check that the expression is in the correct format (ie you are calling a method off of a type Channel
// Get the name of the method call. Something like:
var node = expr.Body as MemberExpression;
if (object.ReferenceEquals(null, node))
throw new InvalidOperationException("Expression must be of member access");
var methodName = node.Member.Name;
// Use reflection to invoke methodName on otherInstanceOfChannel
// Cast the results to TResponse and return
}
正如您所看到的,唯一真正的诀窍是使用Expression&lt;&gt;。类型更改对任何客户端代码都是透明的 - 它们根本不需要更改。 Here is some code让你开始解析表达式树。