我当前的代码如下所示:
// 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”运算符应用于调用结果。
我也想避免这个警告。
调用方法时,不能使用 discard 代替参数,除非它是
out
参数。不过,您可以通过使用双下划线 __
作为参数名称来传达相同的语义,以避免与方法主体中使用的任何真正的丢弃发生冲突。
Foo(__ =>
{
_ = DoAsync();
});
__
从技术上讲并不是丢弃。它只是一个参数名称,传达了程序员忽略参数值的意图。看一下 Chris Mantle 的这篇文章:使用下划线表示 C# lambda 中未使用的参数。
您可以使用
_
放弃返回值。
但带有 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