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

本文关键字:属性 字段 静态 实现 何强制 派生 | 更新日期: 2023-09-27 18:29:37

这是我的抽象类:

abstract class Enemy
{
    protected static abstract float HEALTH
    {
        get;
    }
    float health;
    void someMethod()
    {
        health = HEALTH;
    }
}

这是我的派生类:

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

Mr。编译器说我不能在Enemy类中使成员HEALTH既静态又抽象。

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

有解决方案吗?如果没有,最优雅的解决方法是什么?使属性非静态?

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

static和继承不能一起工作。您可以做的是创建一个可以在派生类中重写的虚拟属性。如果您愿意,您可以在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; }
    }
}

从C#10开始,通过在interface:中使用static abstract成员,现在可以实现与问题的原始实现非常相似的东西

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;
}

除此之外的实现将根据使用情况有所不同,但是如果希望以与原始问题类似的形式维护通用Enemy类,则可以执行的方法之一如下*:

public class Enemy
{
    private float health;
    public void SetEnemy(IEnemy enemy)
    {
        health = enemy.GetHealth();
    }
}

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