如何包装function 财产

本文关键字:dynamic MyClass 财产 function 何包装 包装 | 更新日期: 2023-09-27 18:06:24

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

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

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

如何包装function <dynamic, MyClass>财产

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

你可以这样做:

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);
    };
}

注意,看起来你是在使用委托属性来模拟方法。

有多种方法:

建议一个

为您的委托创建不同的签名:

 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));

建议两个

在dynamic上创建一个扩展方法,为您提供所需的数据。

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