如何强制派生class 实现静态属性 或字段?

How to force derived class to implement a static property or field?

这是我的摘要class:

abstract class Enemy
{
    protected static abstract float HEALTH
    {
        get;
    }

    float health;

    void someMethod()
    {
        health = HEALTH;
    }
}

这是我的派生class:

abstract class BadGuy : Enemy
{
    protected override static float HEALTH
    {
        get { return 1; }
    }
}

先生编译器说我不能在 Enemy class.

中使成员 HEALTH 既静态又抽象

我的目标是强制每个子 class 有一个可以从父 class 访问的静态或常量字段。

有解决办法吗?如果不是,最优雅的解决方法是什么?使 属性 成为非静态的?

static 和继承不能一起工作。你可以做的是创建一个虚拟的 属性,它可以在派生的 class 中被覆盖。如果您愿意,可以在 Enemy 中提供一个基本实现,或者如果您不想,则保留它 abstract

public abstract class Enemy
{
    protected abstract float Health { get; }
}

public class BadGuy : Enemy
{
    private const int BadGuyHealth = 1;
    protected override float Health
    {
        get { return BadGuyHealth; }
    }
}

public class EvenWorseGuy : BadGuy
{
    private const int WorseGuyHealth = 2;
    protected override float Health
    {
        get { return WorseGuyHealth; }
    }
}

通过在 interface:

中使用 static abstract 成员,现在可以实现与问题的原始实现非常相似的东西 starting with C#10
public interface IEnemy
{
    public static abstract float Health { get; }

    public float GetHealth()
    {
        return (float)GetType().GetProperty(nameof(Health)).GetValue(null);
    }
}

public class BadGuy : IEnemy
{
    public static float Health => 1f;
}

超出此范围的实施将根据使用情况有所不同,但是 if 人们希望以与最初的问题然后可以完成的方法之一如下*:

public class Enemy
{
    private float health;

    public void SetEnemy(IEnemy enemy)
    {
        health = enemy.GetHealth();
    }
}

*几乎肯定存在更好的选择,但同样,它们会根据预期用途而有所不同。