DateTime.MaxValue
This DateTime.MaxValue problem I have found in application for some time now, and it seems that not many developers aware of it’s existence. Lets start by looking at how MaxValue is defined:
var MaxValue = new DateTime(3155378975999999999L,
DateTimeKind.Unspecified);
It creates a new instance of DateTime with the Unix timestamp (ticks) representation of the date 9999-12-31 23:59:59.9999999. The problem arises when we think we can do ToString() on DateTime.MaxValue and retain the same MaxValue, lets look at a short example:
var MaxValueToString = DateTime.Parse(DateTime.MaxValue.ToString()); Debug.Assert(DateTime.MaxValue == MaxValueToString);
The above code will fail. This is because the ticks value of the parsed code is 3155378975990000000L, as you can see 9999999 is replaced by zeros.
This is the result because ToString returns the string “9999-12-31 23:59:59” when the correct string would be “9999-12-31 23:59:59.9999999”. If you are looking to define the problem it’s either that ToString don’t have millisecond precision, or that MaxValue uses milliseconds that’s not really needed. This is a fairly common problem when working with dates and serialization, maybe not a serious one but can be hard to spot when debugging. I you you are looking for a fix I would recommend using Ticks, or stop using DateTime.MaxValue.
DebuggerDisplay
When using the Visual Studio debugger you have the possibility to show a custom formatted string about your class. What I have found is that most developers accomplish this by overriding the ToString method. Depending on your user-case this might be exactly what you want, but in most cases you are leaking debug information not relevant to the end user of your class. Instead you should use the DebuggerDisplayAttribute available in System.Diagnostics, this is a simple (read useless) example of the DebuggerDisplayAttribute:
[DebuggerDisplay("\\{ FirstName = {FirstName}, LastName = {LastName} \\}")] public class Person { private readonly string _firstName; private readonly string _lastName; public Person(string firstName, string lastName) { _firstName = firstName; _lastName = lastName; } public string FirstName { get { return _firstName; } } public string LastName { get { return _lastName; } } }
The DebuggerDisplayAttribute is also applicable on:
- Structures
- Delegates
- Enumerations
- Fields
- Properties
- Assemblies
Which means its possible to do thinks like:
[DebuggerDisplay("Count = {Ints.Count}")] List<int> Ints { get { return _ints; } }
There is some limits on what you can do with the expressions, but is should fulfill all your basic needs.
