在C#中覆盖派生类中的静态常量

时间:2017-08-16 03:29:27

标签: c# oop inheritance static

首先,我知道您无法覆盖C#中的静态属性或函数。

这就是我需要的。

public abstract class Effect
{
   public virtual const float duration = 1.0f;

   public void boo() {
         //do some stuff with duration
   }

   public void foo() {
        //do some other stuff with duration
   }
 }

public class EffectA : Effect
{
    public override const float duration = 3.0f;
}

基础和派生类中还有其他一些东西,但是我遇到麻烦的部分是这个静态常量。我需要从没有实例的代码的其他部分引用它,例如EffectA.duration。函数/属性也可以,但是如果静态也不能覆盖它们。

我见过类似的问题,但所有答案似乎都涉及非静态解决方案,即不是将其作为静态函数,而是将其作为实例函数。在我的例子中,在我想查询EffectA.duration的地方,不希望创建一个实例。另外,我不希望有一个实例变量,因为实际上这些类是Unity3D Monobehaviours,并且拥有静态实例没有多大意义,因为在不同的点上有很多被创建和销毁。

如果我希望能够在boo中共享代码并且仍然可以访问每个派生类的静态持续时间,那么理想的工作是什么。

以下是当前代码相关部分的修改版本:

public abstract class Effect : MonoBehaviour
{
    public virtual float kDuration { get { return 1.0f; }}

    public float elapsed = 0.0f;

    // Use this for initialization
    protected virtual void Start()
    {
        elapsed = kDuration;
    }

    // Update is called once per frame
    protected virtual void FixedUpdate()
    {
        elapsed -= Time.fixedDeltaTime;
        if(elapsed <= 0) {
            Destroy(this);
        }

        _doEffect();
    }

    protected abstract void _doEffect();
}

public class EffectA : Effect
{
    public override float kDuration { get {return 3.0f; } }

    protected override void _doEffect()
    {
        //Some behavior
    }
}

这段代码的问题在于没有静态方法来访问效果的kDuration,代码中有很多部分我需要能够获得EffectA.kDuration或类似的没有实例的东西。

2 个答案:

答案 0 :(得分:0)

您正在寻找的内容有点奇怪,但只需使用相同的名称,只需隐藏继承的成员即可保留其静态并提供新值/实现的一个选项: / p>

public abstract class Effect
{
    public const float duration = 1.0f;

    public static void boo()
    {
        // this prints 1.0f
        Console.WriteLine(duration);
    }
}

public class EffectA : Effect
{
    public new const float duration = 3.0f;

    public new static void boo()
    {
        // this prints 3.0f
        Console.WriteLine(duration);
    }
}

注意new关键字只是为你删除了编译器警告,使用相同的名称会导致隐藏。

<强>更新

根据您的评论,以下是您可以避免重复的方法,只需调用共享实现:

public abstract class Effect
{
    public const float duration = 1.0f;

    public static void boo(float val = duration)
    {
        // your complex shared implementation
        Console.WriteLine(val);
    }
}

public class EffectA : Effect
{
    public new const float duration = 3.0f;

    public new static void boo()
    {
        Effect.boo(duration);
    }
}

答案 1 :(得分:0)

可以试试这个,但可能不是正确的方法:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(" duration from Effect " + Effect.duration);
        Console.WriteLine(" duration from EffectA " + EffectA.duration);
        Console.WriteLine(" duration from EffectB " + EffectB.duration);
        Console.Read();
    }
}

class Effect
{
    public const float duration = 1.0f;
}
class EffectA : Effect
{
    public const float duration = 3.0f;
}
class EffectB : Effect
{
}

结果应为:

duration from Effect 1
duration from EffectA 3
duration from EffectB 1

Visual Studio 2015中将有warning但可以通过。 不确定是否可以使用Unity3D MonoDevelop