【问题标题】:Java -> C# Creating Anonymous Instance of Abstract ClassJava -> C# 创建抽象类的匿名实例
【发布时间】:2023-03-17 21:26:01
【问题描述】:

出于培训目的,我正在遵循为 Java 编写的教程,到目前为止,我已成功将其“翻译”为 C#,但是,我现在面临一个问题,我真的不知道如何解决它。我能找到的最接近(?)我的问题的可能答案是this question. 虽然我现在在理解代表和兰巴表达式方面有问题。无论如何,这里是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,但我想保持它流畅到原来的样子。

【问题讨论】:

  • 好吧,委托是这里最明智的方法 - 如果您真的需要描述部分,可以单独使用,也可以作为单独类的一部分。你说你在理解代表方面“有问题”——但你没有提供任何细节,所以很难帮助你更好地理解他们......
  • 我有点理解它们,至少在理论上,多播也是如此,我只是对在实践中使用它们感到非常不确定,因为我没有使用它们的经验。

标签: java c# lambda delegates abstract-class


【解决方案1】:

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

  • 创建私有的、嵌套的、命名的类,并在数组初始化器中引用它们,或者
  • 让构造函数为您计划覆盖的每个抽象方法获取一个委托。

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

第二种方法如下所示:

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是一个委托,所以调用它的语法是一样的:

options[i].invoke(myCreature);

【讨论】:

  • 我想我会在类上放置一个方法来调用委托,而不是将其公开为公共字段...
  • 效果很好,非常感谢。虽然我不太了解“c => c.gainMaxHp()”部分,但为什么“允许”在那里工作?但这与我一开始还没有理解 => 有关。
  • @user3800990 =&gt; 是一种构造 lambda 的方法。 C# 中委托的 Lambda 与 Java 中其基类的匿名类大致相同。不同之处在于,在 Java 中,匿名类可以实现任意数量的方法,而 lambda 只能“实现”一个与其委托签名匹配的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
相关资源
最近更新 更多