11

タイマー/タイマータスククラスを使用するためにJavaで記述されたコードの素晴らしい例を見つけました...

私は現在、これを「Mono for Android」実装のc#に変換していますが、抽象クラスTimerTaskのインライン実装の変換に問題があります

// Here's the original java code

private void resetMapChangeTimer()    
{        
mChangeDelayTimer.schedule(
new TimerTask()        
    {            
      @Override            
      public void run()            
      {                
        // Some code to run           
      }        
    }, longTenSeconds);    
}

これをc#で実装する場合、上記のJavaコードのように個別のクラス(TimerTaskを拡張)を作成せずに、TimerTask(抽象クラ​​ス)とrunメソッドなどから継承されたクラスをインラインで作成したいと思います。

TimerTaskを継承して実装するためだけに個別のクラスを作成するのではなく、この抽象クラスをインラインで作成するためのc#構文について誰かにアドバイスできますか?

4

3 に答える 3

9

C#は、Javaのようにインラインクラスをサポートしていません。匿名メソッドを定義することはできますが、クラス全体を定義することはできません。したがって、抽象クラスを実装する別のクラスを定義する必要があります。

于 2012-06-10T15:30:19.007 に答える
5

ダリンが言うように、匿名関数はここに行く方法です。1ビットの動作を指定しようとしているだけなので、メソッドにを受け入れさせるだけでAction、呼び出し元は無名関数(匿名メソッドまたはラムダ式のいずれか)を使用できます。呼び出し元のコードは次のようになります。

changeDelayTimer.Schedule(() => {
    // Code to run
}, TimeSpan.FromSeconds(10));

または、コードがたくさんある場合は、メソッドグループ変換を使用してメソッドを使用することをお勧めします。

changeDelayTimer.Schedule(MethodContainingCode, TimeSpan.FromSeconds(10));

Javaでは、とにかく匿名内部クラス内の単一のメソッドをオーバーライドする以上のことをしたいと思うことはめったにありません。そのため、C#の無名関数はほとんどの場合ここでも同様に機能します。

コードをJavaからC#に移植するときは、Javaイディオムを保持しようとしないことが重要です-同じ目標を保持しますが、.NETイディオムに移植します。この場合、デリゲートを使用して単一の動作を抽象的な方法で表します。 。

于 2012-06-10T15:32:43.107 に答える
1

既存のJavaクラスを使用/拡張する場合は、汎用ヘルパークラスを実装できます。

class MyTimerTask: TimerTask
{
    private Action action;

    public MyTimerTask(Action action)
    {
        this.action = action;
    }

    public override void Run()
    {
        if(action != null)
            action();
    }
}

その後、匿名メソッドを使用できます。

mChangeDelayTimer.Schedule(new MyTimerTask(() =>
{
    //Do something

}), longTenSeconds);

プロジェクトで最高のC#エクスペリエンスを実現するには、拡張メソッドをさらに追加できます。プロジェクトのどこかにパブリック静的クラスを作成します。

public static class TimerHelper
{
    public static void Schedule(this DelayTimer /*or whatever your timer class is*/ timer, Action action, int delay)
    {
        if(timer == null)
            throw new ArgumentNullException("timer"); //null check needed because this method is not really an instance method

        timer.Schedule(new MyTimerTask(action), delay);
    }
}

次に、次のコードを使用できます。(拡張メソッドを表示するには、TimerHelperクラスが実行中のコンテキストに対して「表示」されている必要があるため、パブリックです)

mChangeDelayTimer.Schedule(() =>
{
    //Do something

}, longTenSeconds);
于 2012-12-14T02:13:23.507 に答える