如何在同一范围内同时丢弃参数和局部变量?

How can I discard both of an argument and a local variable in the same scope?

我目前的代码是这样的:

// for given methods like these:
// void Foo(Action<int> action)
// async Task DoAsync()

Foo(unusedInt =>
{
  var unusedTask = DoAsync();
});

我知道从 C#7.0 开始我可以使用丢弃变量(_),像这样:

Foo(_ =>
{
  var unusedTask = DoAsync();
});

或者,

Foo(unusedInt =>
{
  _ = DoAsync();
});

但是如果我对它们都使用 _,我会遇到错误:

Foo(_ =>
{
  _ = DoAsync();  // error CS0029
});

error CS0029: Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'int'

是否可以丢弃两个未使用的变量?
或者,任何人都可以确认在当前的 C# 规范中这是不可能的吗?


供参考,
如果我省略 unusedTask:

Foo(_ =>
{
  DoAsync();  // warning CS4014
});

warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

我也想避免此警告。

您可以使用 _ 丢弃 return 值。 但是带有 Foo((intvalue) => 的 intvalue 不是 return 值(这是一个匿名方法)。 如果使用 _ 则它是一个普通参数。

但是您必须小心 _ 以丢弃示例中的 Task。 让我举个例子:

//Your async method
public async Task DoAsync()
{
    Console.WriteLine("Start DoAsync");
    await Task.Delay(2000);
    Console.WriteLine("End DoAsync");
}

//a method that expects a Action-Delegate with 1 int as parameter
public void IntAction(Action<int> action)
{
    action(2);
}

现在你可以使用这个了:

//Here the DoAsync wait 2 Seconds and then write 2 to Console
IntAction(async (intvalue) =>
{
    await this.DoAsync();
    Console.WriteLine(intvalue.ToString());
});
//Output is:
//Start DoAsync
//End DoAsync
//2

或者这样:

//Here the DoAsync will not wait and write 2 to Console (discard Task)
IntAction(intvalue =>
{
    _ = this.DoAsync();
    Console.WriteLine(intvalue.ToString());
});
//Output is:
//Start DoAsync
//2
//End DoAsync

调用方法时,discard cannot be used in place of an argument, unless it is an out 参数。不过,您可以通过使用双下划线 __ 作为参数来传达相同的语义,以避免与方法主体中使用的任何真正丢弃发生冲突。

Foo(__ =>
{
    _ = DoAsync();
});