[英]One line method invocation with C# 6 for an awaitable method?
In Jon Skeet's C# 6 post entitled Clean Event Handlers Invocation with C# 6 he shows how you can now write 在Jon Skeet的C#6帖子中,他用C#6命名了Clean Event Handlers Invocation,他展示了你现在如何写作
public void OnFoo()
{
Foo?.Invoke(this, EventArgs.Empty);
}
instead of 代替
public void OnFoo()
{
EventHandler handler = Foo;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
Is there any way to do a one-liner like that if we're talking about an awaitable method? 如果我们谈论一个等待的方法,有没有办法做这样的单线程? If I try
如果我试试
await Foo?.Invoke();
I get the following compile error: 我得到以下编译错误:
The awaiter type
System.Runtime.CompilerServices.TaskAwaiter?
awaiter类型
System.Runtime.CompilerServices.TaskAwaiter?
must have suitableIsCompleted
andGetResult
members (CS4011).必须有合适的
IsCompleted
和GetResult
成员(CS4011)。
Note: I am using Mono (Xamarin Studio for OSX v5.9.5), so the compiler results can vary from what one might get using Visual Studio. 注意:我使用的是Mono(Xamarin Studio for OSX v5.9.5),因此编译器结果可能与使用Visual Studio的结果不同。
@i3arnon Has a good solution, however this is another way that you could do it that wouldn't require adding a field or property. @ i3arnon有一个很好的解决方案,但这是你可以做到的另一种不需要添加字段或属性的方法。
await (Foo?.Invoke() ?? Task.CompletedTask);
or if Task<T>
或者如果
Task<T>
var i = await (Foo?.Invoke() ?? Task.FromResult<T>(default(T)))
Not if you're trying to use the null propagation operator (ie ?.
). 如果您尝试使用空传播运算符(即
?.
),则不会。
When you use this operator the result must be of a nullable type, since it may or may not invoke the method (depending on whether Foo
is null
). 当您使用此运算符时,结果必须是可空类型,因为它可能会或可能不会调用该方法(取决于
Foo
是否为null
)。 Reference types are nullable but value types (structs) are not so for them this operator returns Nullable<T>
( T?
). 引用类型是可空的但是值类型(结构)对于它们不是这样的,这个运算符返回
Nullable<T>
( T?
)。
When you await
something it compiles into calling GetAwaiter
on that awaitable (usually a Task
) and getting an awaiter (usually TaskAwaiter
) that has IsCompleted
, GetResult
and OnCompleted
. await
它时,它会编译为在等待(通常是Task
)上调用GetAwaiter
并获得具有IsCompleted
, GetResult
和OnCompleted
的awaiter(通常是TaskAwaiter
)。 If a type doesn't have all these then it's not awaitable and you can't await it. 如果某种类型没有所有这些,则它不是等待的,你不能等待它。
So in your case, you call Foo?.Invoke()
and get back a Nullable<TaskAwaiter>
(ie TaskAwaiter?
) since TaskAwaiter
is a struct and TaskAwaiter?
那么在你的情况下,你调用
Foo?.Invoke()
并返回一个Nullable<TaskAwaiter>
(即TaskAwaiter?
),因为TaskAwaiter
是一个结构和TaskAwaiter?
doesn't have the required methods (unlike TaskAwaiter
itself) it can't be awaited (it wouldn't have been possible even if TaskAwaiter
was a class since you can't await a null
). 没有所需的方法(与
TaskAwaiter
本身不同)它是无法等待的(即使TaskAwaiter
是一个类也不可能,因为你不能等待null
)。
However, you can simply initialize Foo
with an efficient dummy registration so it wouldn't ever be null
and you wouldn't need to check it: 但是,您可以使用有效的虚拟注册简单地初始化
Foo
,因此它不会为null
,您不需要检查它:
Func<Task> Foo = () => Task.CompletedTask;
public void OnFoo()
{
await Foo();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.