如何包装Func <dynamic,myclass =“”> property </dynamic,>

时间:2011-08-23 21:14:52

标签: c# lambda func

这是简化的设置 - 我有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
}

然后,使用后一种方法有点难看。

这就是为什么即使它仅用于学习目的,我的包装器的方法签名应该如何?我应该如何使用它?

3 个答案:

答案 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();
    });