

基底クラスに仮想関数 virtual OnUpdate() が定義されていてユーザーはこれを派生クラスでオーバーライドして処理を実装するとします。  
この OnUpdate() を Unity のようにコルーチン化して非同期で同時に実行されるようにしたいのですが await/async
を使って実装する場合 virtual メソッドに async キーワードを付けて定義すればいいでしょうか。

[code]

    class Base {
        public async virtual Task OnUpdate () {
        }
    }
    class Derived : Base {
        public async override Task OnUpdate () {
        }
    }
    
[/code]


CC BY-SA 3.0
2015-02-02T07:59:00.933
5765
2015-02-02T08:29:39.903
2015-02-02T08:17:33.210
5005
5005
question
c# game-development
Unity のコルーチンのような機能を async/await を使って実装するにはどうすればいいでしょうか


まず virtual メソッドに async キーワードを付けるのは言語として OK です。派生クラスで override
しても問題ありません。これで問題なく動作します。あと追加情報として async キーワードはメソッドのシグネチャーに含まれません。  
ただし上記のように実装すると2つ問題があります。  
1つ目： await が存在ないメソッドに async をコンパイラーが警告を出します  
2つ目： 普通と異なる書き方をしなければならない戻り値の Task （または `Task<T>` ）がスマートでない  
さらに言えばユーザーは非同期処理されるかどうかはあまり興味が無く async や Task を見たくないのが本音です。  
というわけでここは Non-Virtual Interface イディオムを使って書き換えるとエレガントに書けます。

[code]

    class Base {
        public async Task Update () {
            await Task.Run (() => {
                OnUpdate ();
            });
        }
        protected virtual void OnUpdate () {
        }
    }
    class Derived : Base {
        protected override void OnUpdate () {
        }
    }
    
[/code]

virtual OnUpdate() はこれまで通りの書き方で非同期実行されるようなりました。


CC BY-SA 3.0
2015-02-02T08:16:43.910
5768
2015-02-02T08:29:39.903
2015-02-02T08:29:39.903
5005
5005
5765
answer