Frage

Ich bin versucht zu machen, ein Teil von meinem code mehr fließend.

Ich habe eine string-Erweiterung, die eine HTTP-Anforderung aus dem string und gibt die Antwort als Zeichenfolge.So kann ich etwas tun wie...

string _html = "http://www.stackoverflow.com".Request();

Ich bin versucht zu schreiben, eine Erweiterung, die halten versuchen Sie die Anfrage, bis Sie erfolgreich ist.Meine Signatur sieht so etwas wie...

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
}

Ich beabsichtige, nennen Sie es so etwas wie...

string _html = "http://www.stackoverflow.com".Request.KeepTrying();

Ach, das scheint nicht zu arbeiten =).Ich habe versucht, es in ein lambda erste, aber das scheint nicht zu funktionieren.

string _html = (() => "http://www.stackoverflow.com".Request()).KeepTrying();

Gibt es eine Möglichkeit, das zu tun, was ich versuche zu tun, während die syntax ziemlich fließend?Anregungen sehr geschätzt.

Vielen Dank.

War es hilfreich?

Lösung

Sie können nicht verwenden eine Methode, die Gruppe für die-Erweiterung-Methoden, oder lambda-Ausdrücke.Ich darüber gebloggt, dies vor einer Weile.

Ich vermute, Sie könnten gegossen, um Func<string>:

string _html = ((Func<string>)"http://www.stackoverflow.com".Request)
                    .KeepTrying();

aber das ist ziemlich böse.

Eine alternative wäre die Veränderung Request() zu zurück eine Func, und verwenden:

string _html = "http://www.stackoverflow.com".Request().KeepTrying();

Oder, wenn Sie wollten, halten Sie die Request die Methode selbst ist einfach, fügen Sie einfach einen RequestFunc Methode:

public static Func<string> RequestFunc(this string url)
{
    return () => url.Request();
}

und dann rufen:

string _html = "http://www.stackoverflow.com".RequestFunc().KeepTrying();

Andere Tipps

Warum nicht mit diesem auf den Kopf?

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

Was ist Verbesserung die Anfrage?

string _html = "http://www.stackoverflow.com".Request(RequestOptions.KeepTrying);

string _html = "http://www.stackoverflow.com".Request(RequestOptions.Once);

RequestOptions ist ein enum.Sie könnten auch noch mehr Optionen, timeout Argumente, die Anzahl der Wiederholungen, etc.

ODER

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 Sie können schreiben, eine extension-Methode, erstreckt sich ein Func<T> delegieren, aber der compiler nicht weiß, was du meinst:

string _html = "http://www.stackoverflow.com".Request.KeepTrying(); // won't work

Aber dann, wenn Sie explizit Stimmen die Delegierten arbeiten:

string _html = ((Func<string>)"http://www.stackoverflow.com".Request).KeepTrying(); // works

Die Frage ist hier, ob die code-Lesbarkeit ist wirklich verbessert sich in diesem Fall durch eine extension-Methode.

Ich würde nicht schreiben Sie eine Erweiterungsmethode für string.Eine bestimmte Art, wie der Uri.

Der vollständige code:

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

Aufruf:

 string html = new Uri("http://www.stackoverflow.com").Request().KeepTrying();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top