19

I was writing a method which takes DateTime value as one of it's parameters. I decided that it's optional parameter so I went ahead and tried to make DateTime.MinValue as default.

private void test(string something, DateTime testVar = DateTime.MinValue) {

}

However this gives an error that:

Default parameter value for 'testVar' must be a compile-time constant.

Using this code seems to work just fine.

private void test(string something, DateTime testVar = new DateTime()) {

}

I was given advice to use DateTime.MinValue instead of new DateTime() as it's self-documenting. Since new DateTime() is basically the same thing why DateTime.MinValue can't be used? Also will there be any potential problem if I leave it with new DateTime()?

Community
  • 1
  • 1
MadBoy
  • 10,824
  • 24
  • 95
  • 156
  • 1
    Alternative approach: When does it make sense for a default value to be DateTime.MinValue? I realize it is the *default* for DateTime, but is it actually an appropriate value for the given method? Or maybe if the value is not provided, should it not simply be null? – Anthony Pegram Jan 24 '12 at 18:16
  • I've been using `DateTime.MinValue` everywhere when getting values from SQL which was null as `DateTime` is not nullable. `DateTime?` is. – MadBoy Jan 24 '12 at 18:18
  • 2
    that's the point I'm actually getting at, and it's more applicable here. If you're mapping to a database that supports nullable dates, it seems appropriate to use nullable dates in your code, and then for dates with no values to simply be null, as they are in your database. Merely a thought. – Anthony Pegram Jan 24 '12 at 18:19
  • Instead of using "DateTime.MinValue" as a default value for your optional parameter, I suggest using "default(DateTime)" instead. The compiler likes this better, and the semantics are just as clear if not clearer. – yoyo May 06 '13 at 21:17
  • possible duplicate of [Cannot use String.Empty as a default value for an optional parameter in C# - then what's the point?](http://stackoverflow.com/questions/2701314/cannot-use-string-empty-as-a-default-value-for-an-optional-parameter-in-c-sharp) – nawfal May 16 '13 at 11:03

7 Answers7

13

DateTime.MinValue is defined as:

public static readonly DateTime MinValue

Which is not the same as const. Since a readonly value is not a compile-time constant (i.e. the value is not evaluated at compile-time), it can't be used.

The reason that using new DateTime() works is because that expression is known at compile-time. It's the same as writing default(DateTime). For example, result == true in the following expression:

var result = new DateTime() == default(DateTime);
Yuck
  • 49,664
  • 13
  • 105
  • 135
9

Other answers touch upon why DateTime.MinValue cannot be used, it is not a legal compile time constant. It is a static readonly field, which might very well be constant as far as usage goes, but is not legally constant, nor does it fit the rules for what can be used as a default argument. As for why new DateTime() can be used, see section 10.6.1 of the C# 4.0 Language Specification. Relevant bits:

The expression in a default-argument must be one of the following:

· a constant-expression

· an expression of the form new S() where S is a value type

· an expression of the form default(S) where S is a value type

These result in a zero-initialized instance, basically a bit pattern of all zeros. (See: Section 4.1.2)

However, in this case, I still recommend using a DateTime? value = null as the parameter and default argument, particularly when it's representing a nullable date in a database. MinValue is not the absence of a value. null is.

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
  • Thanks for clear information. I wish there was an option to accept 2 answers (kind of Assisted Answer). – MadBoy Jan 24 '12 at 18:40
5

DateTime.MinValue is readonly, and as per MSDN, readonly values are not compile-time constants:

The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants

Marty
  • 7,464
  • 1
  • 31
  • 52
  • What about `new DateTime`? Why does it work? Can I leave it at `new DateTime` or should I use null and nullable `DateTime?` – MadBoy Jan 24 '12 at 18:22
  • I definitely think you should go with Nullable of Datetime – Magnus Jan 24 '12 at 18:26
  • @Magnus I will probably go with Nullable of DateTime but I would like to get an explanation on the whole topic so it gets out of my head. Everyone seem to focus on DateTime.MinValue which is fine but there's other part of question ;) – MadBoy Jan 24 '12 at 18:31
4

DateTime.MinValue (and DateTime.MaxValue) are public static readonly members rather than compile-time constants.

Rather than use DateTime.MinValue as your default, why not use a nullable DateTime (DateTime?). That makes your intent rather more clear than defaulting to the lowest possible value of datetime.

Something like this:

private void test(string something, DateTime? testVar = null )
{
  if ( testVar.HasValue )
  {
     DoSomethingUsefulWithTimestamp( something , testVar.Value ) ;
  }
  else
  {
     DoSomethingElseWithoutTimestamp( something ) ;
  }
  return ;
}

private void DoSomethingUsefulWithTimestamp( string something , DateTime dt )
{
  ... // something useful
}
private void DoSomethingElseWithoutTimestamp( string something )
{
  ... // something useful
}

Alternatively, set your default in your method body:

private void test(string something, DateTime? testVar = null )
{
  DateTime dtParameter = testVar ?? DateTime.MinValue ;

  DoSomethingUsefulWithTimestamp( something , dtParameter ) ;

}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • The problem is I have DateTime.MinValue all over the code and I don't use nullable DateTime? at all. Fixing this to be consistent across code will be a killer. I could of course do it for this one time thing but I may pass DateTime.MinValue by accident at some point so it's possible that either I will have to take care of it in code as in check for both if null, if DateTime.MinValue or count to not make mistakes :) – MadBoy Jan 24 '12 at 18:26
3

Another alternative would be to have 2 method overloads:

  • One that takes a DateTime parameter
  • One that doesn't take the DateTime parameter

The advantage of this is that you wouldn't have to check if the parameter is null, and it would be clear what your intention is. Internally, method 1 can add a null to the database.

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
1

based on what I am aware of Default value for DateTime is DateTime.MinValue so why not just use new DateTime()

MethodMan
  • 18,625
  • 6
  • 34
  • 52
  • That won't work. Default values have to be compile-time constants. `new DateTime()` is definitely not a compile-time constant. – Jim Mischel Jan 24 '12 at 18:22
  • 1
    @JimMischel as per my question it actually allows to compile just fine if I use new DateTime().. so I'm just wondering/worrying it will shoot me back at some point. – MadBoy Jan 24 '12 at 18:23
  • I understand that but based on what he stated I am only assuming that he would have perhaps declared a variable of DateTime someDateTime = new DateTime(); that was my understanding of his question and I know that this will compile... – MethodMan Jan 24 '12 at 18:24
  • 1
    @JimMischel according to the op `new DateTime()` works just fine. – Magnus Jan 24 '12 at 18:24
0

Use this statement

private void test(string something, DateTime testVar = new DateTime()) {
    if ( testVar != new DateTime() )
    {
        DoSomethingUsefulWithTimestamp( something , testVar.Value ) ;
    }
    else
    {
        DoSomethingElseWithoutTimestamp( something ) ;
    }
}

It should work much better. It is a bummer that null doesn't work, because it would make more sense.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
dikokob
  • 85
  • 3
  • 12