'await' では、型に適切な 'GetAwaiter' メソッドがあることが必要です
次の例では CS1986 が生成されます。
using System.Runtime.CompilerServices;
using System;
using System.Threading.Tasks;
class Program
{
static async Task M(MyTask<int> x)
{
var z = await x;
System.Console.WriteLine(z);
}
}
public class MyTask<TResult>
{
readonly MyTaskAwaiter<TResult> awaiter;
public MyTask(TResult value)
{
this.awaiter = new MyTaskAwaiter<TResult>(value);
}
public static MyTaskAwaiter<TResult> GetAwaiter() => throw new NotImplementedException();
}
public class MyTaskAwaiter<TResult> : INotifyCompletion
{
TResult value;
public MyTaskAwaiter(TResult value)
{
this.value = value;
}
public bool IsCompleted { get => true; }
public TResult GetResult() => value;
public void OnCompleted(Action continuation) => throw new NotImplementedException();
}
GetAwaiter
メソッドは GetAwaiter
という名前の非静的メソッドであり、かつ INotifyCompletion
を実装するオブジェクトのインスタンスを返す必要があります。
GetAwaiter は、INotifyCompletion
インターフェイス (と必要に応じて ICriticalNotifyCompletion
インターフェイス) を実装し、かつそれ自体が 3 つのメンバーを公開する型を返す必要があります [1]:
bool IsCompleted { get; }
void OnCompleted(Action continuation);
TResult GetResult(); // TResult can also be void
この例で CS1986 が発生するのは、GetAwaiter
メソッドが static
であるためです。 このエラーを修正するには、static
修飾子を削除します (そしてメソッドを正しく実装します)。
public class MyTask<TResult>
{
readonly MyTaskAwaiter<TResult> awaiter;
public MyTask(TResult value)
{
this.awaiter = new MyTaskAwaiter<TResult>(value);
}
public MyTaskAwaiter<TResult> GetAwaiter() => awaiter;
}
[1] 何でも待機する
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
.NET に関するフィードバック
.NET はオープンソース プロジェクトです。 フィードバックを提供するにはリンクを選択します。