Java -> C# 创建抽象类的匿名实例

标签 java c# lambda delegates abstract-class

出于培训目的,我正在遵循为 Java 编写的教程,到目前为止我已成功将其“翻译”为 C#,但是,我现在面临一个问题,我真的不知道如何解决它。我能找到的最接近(?)可能的问题答案是 this question.尽管我现在在理解委托(delegate)和兰巴表达式方面存在问题。无论如何,这里是 Java 中的相关代码:

public abstract class LevelUpOption {
  private String name;
  public String name() { return name; }

  public LevelUpOption(String name){
    this.name = name;
  }

  public abstract void invoke(Creature creature);
}

还有另一个类:

public class LevelUpController {

    private static LevelUpOption[] options = new LevelUpOption[]{
        new LevelUpOption("Increased hit points"){
            public void invoke(Creature creature) { creature.gainMaxHp(); }
        },
        new LevelUpOption("Increased attack value"){
            public void invoke(Creature creature) { creature.gainAttackValue(); }
        },
        new LevelUpOption("Increased defense value"){
            public void invoke(Creature creature) { creature.gainDefenseValue(); }
        },
        new LevelUpOption("Increased vision"){
            public void invoke(Creature creature) { creature.gainVision(); }
        }
    };

    public void autoLevelUp(Creature creature){
        options[(int)(Math.random() * options.length)].invoke(creature);
    }

    public List<String> getLevelUpOptions(){
        List<String> names = new ArrayList<String>();
        for (LevelUpOption option : options){
            names.add(option.name());
        }
        return names;
    }

    public LevelUpOption getLevelUpOption(String name){
        for (LevelUpOption option : options){
            if (option.name().equals(name))
                return option;
        }
        return null;
    }
}

我遇到的问题是这部分:

private static LevelUpOption[] options = new LevelUpOption[]{
        new LevelUpOption("Increased hit points"){
            public void invoke(Creature creature) { creature.gainMaxHp(); }
        },
        new LevelUpOption("Increased attack value"){
            public void invoke(Creature creature) { creature.gainAttackValue(); }
        },
        new LevelUpOption("Increased defense value"){
            public void invoke(Creature creature) { creature.gainDefenseValue(); }
        },
        new LevelUpOption("Increased vision"){
            public void invoke(Creature creature) { creature.gainVision(); }
        }
    };

虽然很容易理解它在做什么,但我不知道如何用 C# 编写相对相似的代码。我可以用非常简单的方式解决这个问题,比如使用 if 或 switch case,但我希望保持它平滑到原来的样子。

最佳答案

C# 中没有匿名类,但有两种方法可以实现相同的结果:

  • 创建私有(private)、嵌套、命名类,并在数组初始值设定项中引用它们,或者
  • 让构造函数为您计划重写的每个抽象方法获取委托(delegate)。

第一种方法是不言自明的,但代码会更长一些。命名类应该没问题,因为它们对于公共(public)可见类的实现来说是私有(private)的。

第二种方法可能如下所示:

public class LevelUpOption {
  private String name;
  public String name() { return name; }

  public LevelUpOption(String name, Action<Creature> invoke){
    this.name = name;
    this.invoke = invoke;
  }

  public readonly Action<Creature> invoke;
}

现在您可以像这样初始化数组:

private static LevelUpOption[] options = new [] {
    new LevelUpOption("Increased hit points", c => c.gainMaxHp() ),
    new LevelUpOption("Increased attack value", c => c.gainAttackValue()),
    ...
};

由于 invoke 是委托(delegate),因此调用它的语法是相同的:

options[i].invoke(myCreature);

关于Java -> C# 创建抽象类的匿名实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25037186/

相关文章:

c# - WPF 在触发条件下无法将 "Red"的静态资源识别为红色画笔

带有 lambda 和过滤器的 python 代码

Java 流 : use optional filter() operations on chaining

java - 工厂模式构造对象

java - SnakeYAML 加载到 Guava MultiMap 中

c# - 将焦点从一个控件切换到另一个控件

c# - 如果为空则返回零的 Lambda 表达式

java - 尝试将 XInclude 与 Java 结合使用并使用 xml :id 解析片段

java - 如何让keyevent在小程序中工作?

C# 循环中的多次 ping