Where to check if an object is null or not?
You've got nothing to check in Main
- you're using the new
operator which never returns null (except for Nullable<T>
).
It would be entirely reasonable to check in PrintAge
, particularly if it were made public. (For private APIs it's less important to do argument checking, but it can still be very useful.)
if (person == null)
{
throw new ArgumentNullException("person");
}
These days in C# 3.0 I usually use an extension method for this.
If you design a library, there will be methods exposed to the outer world. You should check the incoming data in this methods. No checks are required in methods that you do not expose, because only your code calls them and its logic should handle all cases you accepted in the exposed method called.
--------------------------
| |
| Library |
| |
------- --------- ---------- |
| | | | | | |
| Outer | | Library | | Library | |
| | ===> | Entry | ===> | Backend/ | |
| World | | Method | | Helpers | |
| | | | | | |
------- --------- ---------- |
| |
| |
--------------------------
If you have accepted the supplied data in the entry method, you should perform the requested action and return the expected result, that is handle all remaining cases.
UPDATE
To clarify the situation inside the library. There might be null checks, but only because of the logic, not because of parameter validation. There are two possibilities for the location of null checks inside the library. The first one if the called method knows how to handle null values.
private CallingMethod()
{
CalledMethod(someData);
}
private CalledMethod(Object parameter)
{
if (parameter == null)
{
// Do something
}
else
{
// Do something else
}
}
And the second situation if you call a method that cannot handle null values.
private CallingMethod()
{
if (someData == null)
{
// Do the work myself or call another method
}
else
{
CalledMethod(someData);
}
}
private CalledMethod(Object parameter)
{
// Do something
}
The whole idea is to reject cases you cannot handle immediately and handle all remaining cases properly. If the input is not valid you throw an exception. This forces the library caller to supply only valid values and does not allow the caller to continue execution with meaningless return values (besides the caller shallows the exception an continues).