【问题标题】:Events and polymorphic design事件和多态设计
【发布时间】:2017-06-13 11:59:51
【问题描述】:

在典型的 RPG 设置中,我正在尝试设计一个可以处理来自角色能力的附加效果的事件设计。

我的主要问题是使这样的系统具有多态性,这样我就可以添加任何我想要的效果,而不会遇到参数或返回类型问题。

这是我迄今为止所做的一个例子:

public abstract class Character
{
    public int CurrentMP { get; set; }
    public List<ISkill> Moveset { get; protected set; }
    // the rest doesn't matter i guess
}

public interface ISkill
{
    string Name { get; set; }
}

public class Weaponskill : ISkill
{
    public int Potency { get; protected set; }
    public IEffects AdditionalEffect { get; set; }
}

public class Warrior : Character
{
    public Warrior ()
    {
        Moveset = new List<Move.ISkill>()
        { 
            new Weaponskill("Sword Slash", 100, new ManaGain(this, 707))
        }
    }
}

在另一个命名空间中,事件。

namespace Additional_Effects 
{
    public delegate void EffectEventHandler(Character character, int gain); 

    public interface IEffects
    {
          event EffectEventHandler Event;
    }

    public class ManaGain : IEffects
    {
        public ManaGain(Character character, int gain)
        {
            Event += OnEffect;
        }

        public event EffectEventHandler Event;

        protected virtual void OnEffect(Character character, int gain)
        {
            character.CurrentMP += gain;
        }

        public void Execute(Character character, int gain)
        {
            if (Event != null)
                Event(character, gain);
        }
    }
}

我的主要问题是委托的参数类型和数量,以及它的返回类型,不灵活。对于另一个 IEffects 实现,我可能需要一个具有完全不同定义的委托。我怎样才能改变我的事件系统来实现呢?

此外,在我作为示例制作的IEffects 实现的情况下,我不确定属性CurrentMP 是否实际上在方法之外进行了修改,我对通过值或引用传递参数有疑问在这里。

最后我想我不能从我的Weaponskill 类中调用我的 Execute 方法,因为它知道IEffect 但不知道它的具体实现,但我不能在接口中有一个 Execute 方法,因为我必须实现它无处不在,即使参数需求在每个具体实现中可能会有所不同。

【问题讨论】:

    标签: c# events interface delegates polymorphism


    【解决方案1】:

    对于代表,也许您可​​以使用不同的签名,例如:C# - Is it possible to have multiple method signatures for an Action<>?

    如果我没记错的话,在 C# 中,只有从 Valuetype 派生的对象是按值传递的。如果需要,您可以使用关键字 ref 通过引用传递它们。但我不认为这是性格的情况。

    目前,您不能从 IEffect 调用执行,因为 Execute 是 Managain 的功能。您必须编写执行的签名以及您希望能够从 IEffect 调用的每个函数。

    【讨论】:

    • 所以我的角色属性真的更新了?那很好。我知道我不能从 IEffect 调用 Execute,但我也不想在每个子类中实现仅对其中一个有用的执行。我正在查看您的链接,第一眼看起来很有希望
    • 我认为 IEffect 没有其他方法。您也可以使用继承,只有母类具有该功能,如果您愿意,您仍然可以在某些子类中覆盖它。但是如果你不想在每个类中都实现一个函数,那么接口并不是一个好的工作方式
    猜你喜欢
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2015-07-23
    相关资源
    最近更新 更多