0

Say I have a constructor like this:

public MyClass(DateTime dateOfBirth, decimal cost)
{
    DateOfBirth = dateOfBirth;
    Cost = cost;
}

I need to add some validation. Do I need to check if these variables are null?

1) If I attempt to do this for cost, then there is a compiler warning saying that a decimal is never null:

if(cost==null) { }

2) If I attempt to do this for dateOfBirth, then there is no problem:

if(dateOfBirth==null) { }

3) If I attempt to do this for dateOfBirth, then there are two compiler errors (one for each variable):

MyClass mc = new MyClass(null, null);

Why is there no compiler error when I test for a DateTime null and a compiler error when I pass a null to a method that expects a DateTime? What validation do I need to do here for nulls?

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
w0051977
  • 15,099
  • 32
  • 152
  • 329
  • @Win I think the question is more about why the `DateTime` `ValueType` doesn't have the compiler warning that `ValueType`s like `Decimal` have when checking for null. – Jonathon Chase Feb 02 '18 at 17:46
  • Possible duplicate of [Comparing structs to null](https://stackoverflow.com/questions/2022425/comparing-structs-to-null) – Gabriel Prá Feb 02 '18 at 17:48
  • @Jonathon Chase, thanks. That is what I am getting at. Can you answer? – w0051977 Feb 02 '18 at 17:51
  • @w0051977 Tools like ReSharper (and by extension, Rider) will mark checks of non-nullable types against null as Always true or Always false depending on the circumstance. I am unsure why the compiler warning was implemented for some structs and not others. – Jonathon Chase Feb 02 '18 at 17:52
  • @Jonathon Chase, I guess it is pointless checking for null inside the constructor? – w0051977 Feb 02 '18 at 17:53
  • @w0051977 If the parameter is a value-type that isn't marked Nullable (ie declared `DateTime? whatever` or `Nullable whatever`) then you can safely assume that it will not be null in your constructor. – Jonathon Chase Feb 02 '18 at 17:58

1 Answers1

1

Both decimal and System.DateTime are value types. This means (unless you declare them as nullable - decimal? or DateTime?) they cannot have a null value.

So, it would be pointless to check whether they are null, since they cannot have a null value. Similarly, it is pointless to pass null for these data types in a constructor or method parameter.

As for whether to make them nullable vs use a logical default (DateTime.MaxValue or decimal.MinValue, for example) is a design choice you will need to make yourself.

And as for why the compiler doesn't complain when you check DateTime for null, I can't really say for sure - that sounds like a compiler bug. But since most developers are not in the habit of checking value types for null, it is not a major cause for concern.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212