开发者

Using -1 as special value in API functions taking numeric arguments

Consider this example function from a fictive game engine API:

function Entity.SetHealth( Number health )
  • Is it bad to have functions like this accept -1 as parameter, causing, in this case, the enti开发者_JAVA百科ty to become invincible?

  • Should I rather use two extra functions: Entity.SetInvincible and Entity.GetInvincible?

Note that this example with invincibility and health is really just made up by me.


There are a lot worse things you can do, and I see that exact approach quite frequently in a lot of game engines and UI frameworks for a variety of tasks (eg. in the command to repeat a movement, setting the repeats to -1 means "repeat forever"). If you get everything else mostly right then criticizing this design choice would just be a nitpick.

That said, the semantics are non-intuitive (-1 is invincible? huh?) so it's better to have the extra functions.


Magic numbers are usually a bad sign, but I wouldn't go so far as to say you should ban them. In other words, if -1 is otherwise an illegal value, you could use that, but I would at least create a constant for it, so that a call to that method would look like this:

someEntity.SetHealth(Health.Infinite)

or similar, naming of the constant is up to you.

However, a better way (in my opinion) is to encapsulate the value, to give it additional data, for instance you could create a type like this in C#:

public struct Health
{
    private readonly int _Value;
    public int Value { get { return _Value; } }

    public Health(int value)
    {
        if (value < 0 || value > SOME_ARBITRARY_MAX_NUMBER)
            throw new ArgumentOutOfRangeException("value");
        _Value = value;
    }

    public static Health Infinite
    {
        get
        {
            Health result = new Health(0);
            result._Value = -1;
            return result;
        }
    }

    public bool IsInfinite
    {
        get
        {
            return _Value == -1;
        }
    }
}

You would then also add the necessary comparison methods, operators, etc. so that you could for instance do this:

Health a = Health.Infinite;
Health b = 100;               // automatic type coercion
if (b < a)                    // custom operator, knows that Infinite > *
    ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜