简体   繁体   English

C#.Net代表

[英]C#.Net Delegates

Say I have a method that calls another method that accepts a string and returns a string, over and over until a condition is met: 假设我有一个方法调用另一个接受字符串的方法并一遍又一遍地返回一个字符串,直到满足条件:

public string RetryUntil(
    Func<string, string> method,
    string input,
    Func<string, bool> condition,
    TimeSpan timeSpan)
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    string response = string.Empty;
    bool conditionResult = false;

    while (stopwatch.Elapsed < timeSpan && conditionResult != true)
    {
        result = method(input);
        conditionResult = condition(result);
        Thread.Sleep(TimeSpan.FromSeconds(0.5));
    }

    return response;
}

It really feels like I should be able to specify the 'method' and 'input' parameters as one parameter. 我觉得我应该能够将'method'和'input'参数指定为一个参数。 So, I want to refactor it so I am able to call it like this, for example: 所以,我想重构它,所以我可以像这样调用它,例如:

RetryUntil(
    ConvertString("hello World"),
    (str) => { return str == "whatever"; },
    TimeSpan.FromSeconds(10));

But obviously, this would pass the result of calling the ConvertString method, (rather than just a delegate to that method) into the Retry method. 但很明显,这会将调用ConvertString方法的结果(而不仅仅是该方法的委托)传递给Retry方法。 Is there a way to pass both delegates and specific parameters for those delegates as one? 有没有办法将这些代理的代理和特定参数作为一个传递? Am I thinking about the entire problem backwards? 我是否倒退了整个问题? It just feels a bit inelegant the way I'm doing it now. 我现在这样做的感觉有点不雅观。

What you're looking for is often called "currying" and is not directly supported in C#, or at least not as well as it is in F#. 您正在寻找的内容通常被称为“currying”,并且在C#中不直接支持,或者至少不如F#中那样。 This is a feature where you can specify some arguments of a function, and get a delegate which takes the remaining arguments (if any) and returns the appropriate value. 这是一个功能,您可以在其中指定函数的某些参数,并获取一个委托,该委托获取剩余的参数(如果有)并返回适当的值。

The easiest way to reference this is like so: 引用它的最简单方法是:

public string RetryUntil(
    Func<string> method,
    Func<string, bool> condition,
    TimeSpan timeSpan)

And then call via 然后拨打电话

RetryUntil(
    () => ConvertString("Hello World!"),
    // ...

the => creates a lambda, which will return the result of the given function. =>创建一个lambda,它将返回给定函数的结果。 Since you're now declaring a method call, you can pass in whatever parameters you wish, or make the lambda itself take some parameters, thus currying arguments. 既然你现在声明了一个方法调用,你可以传入你想要的任何参数,或者使lambda本身采用一些参数,从而调整参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM