0

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

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

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

4

3 回答 3

2

如果我理解正确,它也应该返回 a 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不会调用您传递给的委托。相反,它返回一个委托,当被调用时,它将调用您传递的委托。这种延迟执行可能会令人困惑,但我相信这是您想要的。

于 2011-08-23T21:18:24.720 回答
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);
    };
}

请注意,您似乎正在使用委托属性来模拟方法。对我来说,这闻起来像是一个非常糟糕的架构。

于 2011-08-23T21:17:48.207 回答
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();
    });
于 2011-08-23T21:25:08.080 回答