这是简化的设置 - 我有API(我对API没有控制权),它暴露了一个Func属性,如下所示:
public Func<dynamic, MyClass> FuncProperty { get; set; }
通常它的使用方式如下:
api.FuncProperty = s =>
{
do1();
do2();
return new MyClass(); //simplified
}
在整个地方使用类似的代码(当然{}中的内容是不同的),我想为所有这些添加常用功能,我想创建一个“包装”方法,我可以使用像这样:
api.FuncProperty = MyWrapperMethod(
s =>
{
do1();
do2();
return new MyClass();
});
我知道我可以将所有这些调用编辑为:
api.FuncProperty = s =>
{
DoMyCommonFunctionality();
//... as before
}
但如果我的常用功能如下:
using(var disposable = SetSomeState())
{
//the stuff which previously was in the lambda
}
然后,使用后一种方法有点难看。
这就是为什么即使它仅用于学习目的,我的包装器的方法签名应该如何?我应该如何使用它?
答案 0 :(得分:2)
如果我理解你的话,它也应该返回Func<dynamic, MyClass>
,如下所示:
public static Func<dynamic, MyClass> MyWrapperMethod(Func<dynamic, MyClass> func)
{
// Validation if you want
return d =>
{
using(var disposable = SetSomeState())
{
return func(d);
}
};
}
这是您想要的using
声明的示例。
请注意,调用MyWrapperMethod
不会调用您传递给它的委托。相反,它返回一个委托,当被调用时,它将调用您传递的委托。这种延迟执行可能令人困惑,但我相信这就是你想要的。
答案 1 :(得分:1)
你可以这样做:
public Func<dynamic, MyClass> MyWrapperMethod(Func<dynamic, MyClass> func)
{
if (func == null)
throw new ArgumentNullException("func");
return s => {
DoMyCommonFunctionality();
// Execute original function
return func(s);
};
}
请注意,您似乎正在使用委托属性来模拟方法。这对我来说就像是一个非常糟糕的建筑。
答案 2 :(得分:0)
有多种方法可以做到这一点:
建议一
为您的代表创建不同的签名:
public Func<HelperObject<dynamic>, MyClass> FuncProperty { get; set; }
然后你的方法改变如下:
api.FuncProperty = h =>
{
//h.Model is the dynamic
//h.CommonHelperFunction()
return new MyClass();
};
然后像这样调用:
api.FuncProperty(new HelperObject(someDynamic));
建议二
在动态上创建一个扩展方法,为您提供所需的数据。
public static MyHelperClass CreateHelper(this object obj)
{
return new MyHelperClass();
}
然后你就可以这样使用它了:
api.FuncProperty = s =>
{
var helper = (s as object).CreateHelper();
return new MyClass();
};
建议三
从对象中删除作为属性的委托,并将其更改为方法抽象:
public MyClass ExecuteFunc(Func<dynamic, MyClass> selector)
{
Func<MyClass> helper = () =>
{
DoCommonFunctionality();
return selector(x.Model);
};
return helper();
}
然后你会这样打电话:
api.ExecuteFunc(x =>
{
return new MyClass();
});