11

我发现了一个很好的用java编写的代码示例,用于使用定时器/定时器任务类......

我目前正在将其转换为 c# 用于“Mono for Android”实现,但在转换抽象类 TimerTask 的内联实现时遇到了麻烦

// Here's the original java code

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

当我在 c# 中实现它时,我想从 TimerTask(抽象类)和 run 方法等内联创建一个继承类,而不必像上面的 java 代码那样创建一个单独的类(扩展 TimerTask)。

谁能建议我使用 c# 语法来内联创建这个抽象类,而不是创建一个单独的类来继承和实现 TimerTask?

4

3 回答 3

9

C# 不支持 Java 中的内联类。您可以定义匿名方法,但不能定义整个类。所以你必须定义一个单独的类来实现抽象类。

于 2012-06-10T15:30:19.007 回答
5

正如 Darin 所说,匿名函数是通往这里的路。您只是想指定一种行为,所以只需让方法接受 anAction然后调用者就可以使用匿名函数(匿名方法或 lambda 表达式)。调用代码如下所示:

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 回答