使无参数方法像Func< ReturnT>一样运行
-
03-07-2019 - |
题
我正在尝试让我的代码的一部分更流畅。
我有一个字符串扩展,它从字符串中发出HTTP请求,并以字符串形式返回响应。所以我可以做点像......
string _html = "http://www.stackoverflow.com".Request();
我正在尝试编写一个扩展程序,它将继续尝试请求,直到成功为止。我的签名看起来像......
public static T KeepTrying<T>(this Func<T> KeepTryingThis) {
// Code to ignore exceptions and keep trying goes here
// Returns the result of KeepTryingThis if it succeeds
}
我打算称它为......
string _html = "http://www.stackoverflow.com".Request.KeepTrying();
唉,这似乎不起作用=)。我试着先把它变成一个lambda,但这似乎也不起作用。
string _html = (() => "http://www.stackoverflow.com".Request()).KeepTrying();
在保持语法流畅的同时,有没有办法做我想做的事情? 建议非常感谢。
感谢。
解决方案
您不能将方法组用于扩展方法或lambda表达式。我不久前在博客上发表了这篇文章。
我怀疑你可以投射到 Func&lt; string&gt;
:
string _html = ((Func<string>)"http://www.stackoverflow.com".Request)
.KeepTrying();
但那非常讨厌。
另一种方法是将 Request()
更改为 return 一个Func,然后使用:
string _html = "http://www.stackoverflow.com".Request().KeepTrying();
或者如果您想保持 Request
方法本身简单,只需添加 RequestFunc
方法:
public static Func<string> RequestFunc(this string url)
{
return () => url.Request();
}
然后致电:
string _html = "http://www.stackoverflow.com".RequestFunc().KeepTrying();
其他提示
为什么不把它转过来?
static T KeepTrying<T>(Func<T> func) {
T val = default(T);
while (true) {
try {
val = func();
break;
} catch { }
}
return val;
}
var html = KeepTrying(() => "http://www.stackoverflow.com".Request());
如何增强请求?
string _html = "http://www.stackoverflow.com".Request(RequestOptions.KeepTrying);
string _html = "http://www.stackoverflow.com".Request(RequestOptions.Once);
RequestOptions
是一个枚举。您还可以有更多选项,超时参数,重试次数等。
OR
public static string RepeatingRequest(this string url) {
string response = null;
while ( response != null /* how ever */ ) {
response = url.Request();
}
return response;
}
string _html = "http://www.stackoverflow.com".RepeatingRequest();
AFAIK你可以编写一个扩展 Func&lt; T&gt;
委托的扩展方法,但编译器不知道你是什么意思:
string _html = "http://www.stackoverflow.com".Request.KeepTrying(); // won't work
但是,如果您明确地转换委托将工作:
string _html = ((Func<string>)"http://www.stackoverflow.com".Request).KeepTrying(); // works
这里的问题是,在这种情况下,通过扩展方法是否真正改善了代码可读性。
我不会为字符串编写扩展方法。使用更具体的类型,例如 Uri
。
完整代码:
public static class Extensions
{
public static UriRequest Request(this Uri uri)
{
return new UriRequest(uri);
}
public static UriRequest KeepTrying(this UriRequest uriRequest)
{
uriRequest.KeepTrying = true;
return uriRequest;
}
}
public class UriRequest
{
public Uri Uri { get; set; }
public bool KeepTrying { get; set; }
public UriRequest(Uri uri)
{
this.Uri = uri;
}
public string ToHtml()
{
var client = new System.Net.WebClient();
do
{
try
{
using (var reader = new StreamReader(client.OpenRead(this.Uri)))
{
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
// log ex
}
}
while (KeepTrying);
return null;
}
public static implicit operator string(UriRequest uriRequest)
{
return uriRequest.ToHtml();
}
}
致电:
string html = new Uri("http://www.stackoverflow.com").Request().KeepTrying();
不隶属于 StackOverflow