views:

109

answers:

5

I have a constructor that need to validate passed data.

public Rational(int m, int n)

If n == 0 i should inform user about that.
I know 3 ways to do that.

1) Just make return; in coustructor
2) Generate an exception
3) Create a static method that will create an object

r = new Rational();
r = Rational.GetObject(1,2);

What is the best way to validate data in constructor?

+8  A: 

Considering you're dealing with an invalid argument being passed into the constructor, I would probably throw a new ArgumentException from inside the constructor.

Justin Niessner
I'm sure you meant `ArgumentException`.
JSBangs
@JSBangs @SLaks - Indeed I did mean ArgumentException. Either that or, as Mark Byers mentioned, ArgumentOutOfRangeException.
Justin Niessner
My teacher said that Exception in coustructor is very bad way. He said to do it as a 3rd way
Sergey Gavruk
@Sergey Gavruk - If it's a pattern that Microsoft follows (throwing Exceptions from constructors), I'm not going to feel too bad doing it myself. Check out the List<T>(IEnumerable<T>) constructor: http://msdn.microsoft.com/en-us/library/fkbw11z0.aspx and look at the Exceptions it will throw.
Justin Niessner
@Justin Niessner, thank you
Sergey Gavruk
It is a pretty common practice in .net development to throw exceptions in constructors if the arguments do not satisfy some invariant rule. This works even better if the class is immutable. I think I remember hearing something about this being a problem in C++, but that is outside of my area of knowledge.
PhilB
+1  A: 

Generate an exception: you can't afford to let the user play with (create) an object that won't work.

Jonathan Leffler
+2  A: 

Two things:

  • Throw an ArgumentOutOfRangeException in the constructor.
  • Validate the value the user enters before calling the constructor and generate a suitable error message. The exception should be a last resort.
Mark Byers
Validate data before constructor should user that usees my class. But he may dont know about it
Sergey Gavruk
@Sergey Gavruk: That's why you have both mechanisms - your users *should* validate all inputs but if they forget to do this then your code will fail early and give them a helpful error message so that they can see how to fix their code.
Mark Byers
Many people don't like exceptions in contructor. They say that it is very bad way
Sergey Gavruk
@Sergey, it is worse to have an object in an invalid state and use it as if it is valid.
aqwert
+2  A: 

You should throw an ArgumentOutOfRangeException in the constructor. (Making sure to specify the parameter name in addition to the exception message)

In addition, you can also make a static TryCreate method:

public static bool TryCreate(int m, int n, out Rational result);

or

public static Rational? TryCreate(int m, int m);

This method would return false or null if the parameters are invalid instead of throwing an exception; similarly to int.TryParse.

SLaks
A: 

I'd go with throwing an System.ArgumentException from the constructor.

naacal