开发者

Best way to enforce constraints when constructing an object

I have a Prize object that has a constructor with a single int parameter pence. I don't want ot allow negative values to be passed in. What is the best way to enforce this restriction? Shall I throw an exception from constructor? Or write a factory method?

EDIT: The Prize object was used as an example of a general role. Using uint is a good answer in this specific example not as 开发者_JAVA百科a general role. I use 3.5 without additional code contracts libraries.


I have a Prize object that has a constructor with a single int parameter pence. I don't want ot allow negative values to be passed in.

Why don't you use the uint datatype for pence instead? Then it's guaranteed already that it's a positive value and you don't have to enforce this constraint yourself.

In general for enforcing constraints the mantra is "fail as soon as possible" (also see fail fast) so you should either throw an exception in the constructor or enforce your constraints with a code contract. I don't really see how a factory method would help in this context.


The design choice of how you construct an instance (ctor or factory) is independent of argument validation. Usually you should favor constructors (for example, see this answer for a relevant excerpt from Framework Design Guidelines):

When to use Factory method pattern?

The simple way to validate arguments are, of course, guard clauses that throw the appropriate exception:

public Prize(int pence)
{
    if (pence < 0)
    {
        throw new ArgumentException(...);
    }

    /* Do stuff */
}

Then there's also Code Contracts that you may want to look into. I think those allow you to annotate your requirements, but I haven't had the opportunity to try them yet.


Just as you would use an int instead of a string to enforce passing in a valid integer, if you want only non-negative integers, how about using the appropriate type: uint.


I agree with BrokenGlass 100%.

One 'trick' that you can use to have an int property on the prize object only allow positive integers without changing the data type to uint is:

public class Prize 
{
    private int _pence = 0;
    public int Pence 
    { 
      get { return _pence; }
      set { _pence = Math.Max(value, 0); }
    }

    public Price(int pence) 
    {
        Pence = pence;
    }
}

This doesn't prevent one from using reflection to set a negative number when using your class, but it does prevent negatives from being entered normally.

If you don't want to silently ignore negative values, you could throw an exception or even call Math.Abs.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜