如何修复这个以 func 作为参数的 .NET 方法?

How to fix this .NET method that has a func as an argument?

我有以下方法

public async Task<dynamic> FooAsync(dynamic parameters, 
                                    CancellationToken cancellationToken)
{..}

但我似乎无法找到使用 this 方法正确调用它的方法:

public async Task<dynamic> TryAsync(Func<dynamic, CancellationToken, Task<dynamic>> func)
{
    try
    {
        await func(); // Doesn't compile. Says it missing the 2 arguments.
    }
    catch(Exception exception)
    {
        ..
    }
}

例如将 FooAsync 传递给 TryAsync ..

的代码
public async Task PewPewAsync(..)
{
    ...
    // TODO: Get this to work/compile :(
    var result = await TryAsync(FooAsync(parameters, cancellationToken);
    ...
}

试试这个

public async Task<dynamic> TryAsync(Func<dynamic, CancellationToken, Task<dynamic>> func, dynamic parameters, CancellationToken cancellationToken)
{
    try
    {
        await func(parameters, cancellationToken);
    }
    catch(Exception exception)
    {
        ..
    }
}

然后这样称呼它

public async Task PewPewAsync(..)
{
    ...
    var result = await TryAsync(FooAsync, parameters, cancellationToken);
    ...
}

原因是您需要将参数单独传递给您想要call/wrap的函数,以便您可以将它们传递给实际调用。在您的原始代码中,您正在调用函数并将 return 值作为参数传递给 TryAsync,而不是传递对函数本身的引用。

这取决于您尝试使用该 TryAsync 实现的具体目标。另一个答案中显示了一种方法。另一种方式是

public async Task<dynamic> TryAsync(Func<Task<dynamic>> func) {
    try {
        var result = await func();
        return result;
    }
    catch (Exception exception) {
        // do something
        return null;
    }
}

这样调用

var result = await TryAsync(() => FooAsync(parameters, cancellationToken));

您有一个接受两个参数(dynamicCancellationToken)的委托,并且您试图用零参数调用它。

根据你想做什么,你可以让 TryAsync 接受两个参数,然后在调用它时传递它们:

public async Task<dynamic> TryAsync(
    Func<dynamic, CancellationToken, Task<dynamic>> func,
    dynamic parameters, CancellationToken cancellationToken)
{
    try
    {
        return await func(parameters, cancellationToken);
    }
    catch(Exception exception)
    {
        ..
    }
}

TryAsync(FooAsync, parameters, cancellationToken);

或者您可以使用一个没有任何参数的委托,并在调用它时使用 lambda:

public async Task<dynamic> TryAsync(Func<Task<dynamic>> func)
{
    try
    {
        return await func();
    }
    catch(Exception exception)
    {
        ..
    }
}

TryAsync(() => FooAsync(parameters, cancellationToken));

这取决于 - 你想什么时候执行FooAsync

TryAsync 之前?如果你想执行 TryAsync 中的所有内容,你可以使用:

    public async Task<dynamic> FooAsync(dynamic parameters, CancellationToken cancellationToken) {
        return await Task.FromResult("x");
    }

    public async Task<dynamic> TryAsync(Func<Task<dynamic>> func) {
        try {
            return await func(); // Doesn't compile. Says it missing the 2 arguments.
        }
        catch (Exception exception) {
            return Task.FromResult(false);
        }
    }

    public async Task PewPewAsync() {
        var parameters = "x";
        var cancellationToken = CancellationToken.None;
        var result = await TryAsync(() => FooAsync(parameters, cancellationToken));
    }