【问题标题】:Delegates with varying number of parameters具有不同数量参数的代表
【发布时间】:2020-03-03 15:27:30
【问题描述】:

我编写了一个 DLL,它调用我无权访问的第三方 API。

由于用户如何退出并重新启动应用程序,每个方法都有很多围绕检查访问和刷新令牌的逻辑,以便通过 API 进行身份验证。 (以及错误处理处理)这导致每个不同的 API 调用都有大量重复的代码。

我想重构它,这样我就可以将我想要的响应对象的类型传递给一个名为 ExecuteApiCall 的通用方法。然后可以为特定的 REST 调用调用适当的方法。

我用以下签名创建了这个方法:

private T ExecuteApiCall<T>(string name, Action<T> requestCall) where T : IApiResponse, new()

这正如我所料。我现在遇到的问题是一些请求需要额外的参数,我无法将不同数量的参数传递给 Action 委托。

我该如何处理这个问题?

我想换成

Action<T, ApiRequestParameters>

其中 ApiRequestParameters 是一个包含所有可能参数的类,面向公众的方法可以在调用私有 ExecuteApiCall 之前设置它需要的内容。但这并不是最佳实践。

我真的希望这对某人有意义,并提前感谢。如果需要,很乐意提供更多代码示例。

以下需要处理

ExecuteCallA()
{
    //The API call is done here using RestSharp
}

ExecuteCallB(string aParameter)
{
    //The API call is done here using RestSharp
}

ExecuteCallC(string aParameters, int anotherParameter)
{
    //The API call is done here using RestSharp
}

或者将 Action 设置为类似这样会更容易吗?

Action<T, object, object, object>

这样它就可以处理额外的参数,而忽略任何它不需要的参数。

编辑:

感谢 Sean 的建议,这很可能是我的建议。我的另一个选择,再次不确定这里的最佳实践......

应该让公共签名包含方法参数并将它们设置为私有字段。

private string myParameter;
public ApiResponseA GetWhatever(string a)
{
    myParameter = a;
    ExecuteApiCall<ApiResponseA>();
    myParameter = null;
}

然后将负责实际 API 调用的私有方法更改为使用私有字段而不是参数。想法?

【问题讨论】:

  • 您总是可以将x =&gt; ExecuteCallB(x, additionalstuff) 之类的东西传递为Action&lt;T&gt;

标签: c# generics delegates


【解决方案1】:

我会为一定数量的参数添加重载。例如:

private T ExecuteApiCall<T>(string name, Action<T> requestCall) where T : IApiResponse, new();

private T ExecuteApiCall<P1, T>(string name, P1 p1, Action<P1, T> requestCall) where T : IApiResponse, new()

private T ExecuteApiCall<P1, P2, T>(string name, P1 p1, P2 p2, Action<P1, P2, T> requestCall) where T : IApiResponse, new()

// etc

实现起来有点重复,但一旦你完成了它,你就可以忘记它,它会让你向用户公开的 API 更加清晰和可预测。

【讨论】:

  • 谢谢肖恩,我认为这是要走的路,因为我不能忽略额外的参数,因为那些不使用它们的方法会导致编译错误,如果我不在那里添加它们并且这太可怕了。
  • @RyanThomas 如果您查看 Action 和 Func 的定义,您会发现 Microsoft 在实现 Action 时做了同样的事情。每个对象有 16 个定义,代表每个对象的 0-16 个参数版本。
  • 我想另一种选择是让公共访问方法具有参数,将这些设置为私有字段的值,然后可以通过执行 REST 调用的方法访问该私有字段并消除对参数的需要根本就在进行实际调用的私有方法上。想法?
  • 或者甚至只是将第二个对象作为动态对象传递?不过这更容易出错。
  • @RyanThomas - 我会避免使用dynamic。正如您所说,它容易出错并且不会给您任何编译时安全性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
相关资源
最近更新 更多