While writing an article Dealing with dynamic SQL in SQL Server we have crushed on a trivial C# code.
Consider a declaration:
public enum Direction { Asc, Desc } public struct Order { public string Field { get; set; } public Direction Direction { get; set; } } public class DateRange { public DateTime? From { get; set; } public DateTime? To { get; set; } } public class Request { public DateRange CreatedAt { get; set; } public string Summary { get; set; } [XmlElement] public int[] State { get; set; } public DateRange UpdatedAt { get; set; } [XmlElement] public Order[] Order { get; set; } }
and a code:
... var request = new Request { CreatedAt = { From = new DateTime(2014, 1, 1) }, Order = new[] { new Order { Field = "CreatedAt" } } }; ...
It was hard to believe that this simple variable declaration throws NullReferenceException.
NullReferenceException
In fact we could not realize what the reason is until we have decompiled that code and poked into IL.
It appears that the problem is with the line:
CreatedAt = { From = new DateTime(2014, 1, 1) },
It's implemented like this:
var range = request.CreatedAt; range.From = new DateTime(2014, 1, 1) ; range.To = null;
In other words it assumes the instance stored in property CreatedAt is not null, and it reinitializes all its properties.
CreatedAt
null
In contrast the following works as expected (no exception is thrown):
CreatedAt = new { From = new DateTime(2014, 1, 1) },
as it creates a new instance and assigns it to a property.
We think that this is very error prone, so if it's how C# is assumed to be then it's the problem of the spec, otherwise it's the problem of Microsoft implementation of C# (at least in VS 2010 - 2013).
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u