我从事C#编程已经有六年了,我一直在尝试学习该语言提供的更多功能,所以我很好奇是否可以指定继承的类来实现类似委托的行为,但是整个对象而不是单个方法。

我正在使用带有Buff / Debuff系统的C#在Unity中制作RPG游戏。所有不同的Buff / Debuff都继承自Aura基础类。应用Auras的角色能力从AuraAbility基础类继承,而AuraAbility基础类又从Ability基础类继承。这是上下文的一些相关代码。

public abstract class Ability
{
    public string Name;
    public float PowerCoefficient;
    public float CastTime;

    public float Cooldown;
    public float CooldownRemaining;

    public Entity Owner;
    public Entity Target;

    public Ability(Entity owner = null)
    {
        Owner = owner;
    }

    protected virtual void Do()
    {
        CooldownRemaining = Cooldown
    }

    /* Other Methods */
}

public class AuraAbility : Ability
{
    /*
     * This would be whatever the delegate-like object would be
     */
    public Aura SpecifiedAura;

    public AuraAbility(Entity owner = null)
        : base(owner)
    {
        // Overridden constructor functionality
    }

    protected override Do()
    {
        /*
         * This is where I want to construct the specified Aura type
         * This isn't real code but just an example of what I want
         */
        Target.AddAura(new SpecifiedAura(Target, Owner));

        base.Do();
    }
}

public class Attune : AuraAbility
{
    public Attune(Entity owner = null)
        : base(owner)
    {
        Name = "Attune";

        CastTime = 0f;
        Cooldown = 4.0f;

        /*
         * Not real code - but this is where I would specify which inherited aura type I wanted
         */
        SpecifiedAura = AttuneBuff;
    }
}

public abstract class Aura
{
    public Raider Owner;
    public Entity Applier;

    public float Duration;
    protected float DurationRemaining;

    public Aura(Entity owner, Entity applier = null)
    {
        Applier = applier;
        Owner = owner;
    }

    /* Other Methods */
}

public class AttuneBuff : Aura
{
     public AttuneBuff(Entity owner, Entity applier = null)
         : base(owner, applier)
     {
         // Overridden constructor functionality
     }

     /* Overridden Methods */
}


现在,我想知道是否有一种方法可以指定要由AuraAbility.Do()构造和添加的继承的Aura类型。有点类似于在定义回调时如何指定委托方法,我想指定“委托对象类型”,但是我不确定正确的术语是什么,或者这种功能是否存在。

我的后备解决方案是仅重写Attune中的Do()来构造和添加AttuneBuff。我认为这是最直接的解决方案,但是我不想这样做,因为它需要不必要地覆盖Do()和复制代码。

另一个解决方案是使AuraAbility通用,例如public class AuraAbility<T> where T : Aura。并且具有像public class Attune : AuraAbility<AttuneBuff>这样的继承能力。并使用Activator构造AuraAbility.Do()中的泛型类型。

由于我已经有了解决方案,因此出于好奇和学习的考虑,我主要是出于问询,因为我不确定要调用哪种类型的功能,甚至不确定这种功能是否存在。

最佳答案

您可以做您想做的事。

public abstract class Ability
{
    public Entity Owner;
    public Entity Target;

    public Ability(Entity owner = null)
    {
        Owner = owner;
    }

    protected abstract void Do();

    /* Other Methods */
}

public abstract class AuraAbility : Ability
{
    private readonly Func<Entity, Entity, Aura> auraFactory;

    protected AuraAbility(Entity owner,
        Func<Entity, Entity, Aura> auraFactory)
        : base(owner)
    {
        this.auraFactory = auraFactory;
    }

    protected override void Do()
    {
        Target.AddAura(auraFactory(Owner, Target));
    }
}

public class Attune : AuraAbility
{
    public Attune(Entity owner = null)
        : base(owner, (o, target) => new SpecifiedAura(o, target))
    {
    }
}


请注意,程序的某些(很多)方面将受益于大量的代码审查。我建议在代码审查堆栈交换中发布一个帖子。

10-05 21:56