如何在同一个作用域中丢弃参数和局部变量?

问题描述

我当前的代码如下:

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

错误CS0029:无法将类型'System.Threading.Tasks.Task'隐式转换为'int'

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


供参考,
如果我省略unusedTask

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

警告CS4014:由于未等待此调用,因此在调用完成之前将继续执行当前方法。考虑将“ await”运算符应用于调用结果。

我也想避免此警告。

解决方法

您可以使用_放弃返回值。 但是带有Foo((intvalue) =>的intvalue不是返回值(这是一个匿名方法)。 如果您使用_,则它是正常参数。

但是您必须谨慎使用_来丢弃示例中的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参数,否则不能使用out代替参数。不过,您可以通过使用双下划线__作为参数来传达相同的语义,从而避免与方法主体中使用的任何真实舍弃产生冲突。

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