【问题标题】:Is it possible to make an interface method return the type of another method with a generic type parameters in C#?是否可以在 C# 中使用泛型类型参数使接口方法返回另一个方法的类型?
【发布时间】:2020-09-18 05:11:10
【问题描述】:

所以我正在尝试创建一些流畅的代码来执行网络请求。我希望它看起来像这样......

// Result should be of type MyClass
var result = await _webRequests.Get("Api/Route/Here")
                               .Returns<MyClass>()
                               .HasToken("MY_TOKEN")
                               .ExecuteAsync();

// Result should be of type HttpResponseMessage
var result = await _webRequests.Get("Api/Route/Here")
                               .HasToken("MY_TOKEN")
                               .ExecuteAsync();

我的目标是如果没有指定 Returns 方法,则返回一个 HttpResponseMessage,如果指定了,则返回指定的类型。

_webRequests 是一个接口,里面有一些基本的 HttpMethod 调用

IUseRequired Get(string url);
IUseRequired Post(string url);

那么IUseRequired接口就有调用所需的方法了……

IUseOptionalOrExecute UsesApi(string apiName);

UsesApi 方法所做的只是告诉在使用 IHttpClientFactory 时要使用哪个 HTTPClient。

现在 IUseOptionalOrExecute 接口是问题开始的地方...

IUseOptionalOrExecute Returns<TReturn>();
IUseOptionalOrExecute HasToken(string token);
Task<TReturn> ExecuteAsync();

我希望它看起来像这样,因此传入 Returns 方法的任何内容都将用作 ExecuteAsync 方法的返回值。当然这不起作用,因为 ExecuteAsync 不知道 TReturn 是什么。我曾考虑在调用 Returns 方法时将类型存储为变量,但我无法将 Execute 的返回类型设置为变量类型。或者我可以吗? 任何人都知道我可以解决这个问题的方法吗?谢谢!

【问题讨论】:

  • 正如 mcc 指出的那样,有一种方法,但这意味着您必须创建一个全新的泛型类型,并且一旦您处理了所有可能性(例如,您是否试图阻止人们第二次使用不同类型的电话拨打Returns?)。请仔细注意更改原因,并确保您的耦合选择反映了这些原因。您真的希望必须为每个方法调用单独提供令牌,而不是使用自动将给定令牌添加到每个请求的服务吗?你为什么要编写自己的库?
  • 我们正在尝试使用我们公司中其他人可以调用的库,这样他们就可以使用几行代码,而不是每次都编写大量代码。这样的设置更好,所以我们不会让每个人都使用自己的方式访问 API,并且代码开始看起来相似并且更容易为每个人调试。我确实同意自动设置令牌会更好,尽管这对于通用库来说既困难又混乱。此外,可能存在需要令牌的端点,而其他端点则不需要,因此无论如何都需要动态更改它。
  • 我绝对推荐查看为相同目的编写的其他库。例如,如果您使用 RestSharp,您就不必花时间创建流畅的 API 来构建请求,您可以更专注于构建工厂和包装器,专注于您的应用的特定内容。

标签: c# generics interface httpclient fluent


【解决方案1】:

使用 typeof(TReturn) 确定类型。

【讨论】:

  • 这更适合作为评论而不是答案。当你写一个答案时,试着在你的答案中更具描述性
【解决方案2】:

Returns&lt;TReturn&gt; 函数的存在有充分的理由吗?

当我实现我的 HTTP 客户端时,我在 ExecuteAsync&lt;TReturn&gt; 上指定了返回类型,因为不需要事先知道类型,因此我避免解决你的问题。

如果您出于某种原因需要该类型,我认为您可能需要执行 IUseOptionalOrExecute&lt;TReturn&gt; Returns&lt;TReturn&gt;(); 并处理所有必要的复杂情况。

如果ExecuteAsync&lt;TReturn&gt; 不足以解决您的问题,我可以对此进行扩展。

【讨论】:

  • 我确实想过这个,我只是想要一个返回方法,以便其他可能使用此接口的人知道他们可以通过查看可以调用的方法来指定返回。我认为 ExecuteAsync 可能是我拥有的最佳选择,感谢您的洞察力。
  • 好吧,你可以同时拥有HttpResponseMessage ExecuteAsync()TReturn ExecuteAsync&lt;TReturn&gt;(),这应该为 API 的用户提供足够的信息,让他们知道它可以做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多