为什么下面的C#代码在可为Null的DateTime初始化时抛出NullReferenceException?

为什么下面的C#代码在可为Null的DateTime初始化时抛出NullReferenceException?,c#,nullreferenceexception,nullable,C#,Nullreferenceexception,Nullable,下面是一些简单的代码: static void Main(string[] args) { var coll = new List<string> {"test", "test2", "test3"}; var filteredColl = coll.Select(x => x).ToList(); if (!filteredColl.Any()) { DateTime?

下面是一些简单的代码:

    static void Main(string[] args)
    {
        var coll = new List<string> {"test", "test2", "test3"};

        var filteredColl = coll.Select(x => x).ToList();

        if (!filteredColl.Any())
        {
            DateTime? date = new DateTime();

            filteredColl = coll.Where(x => date.GetValueOrDefault().Date.ToString(CultureInfo.InvariantCulture) == x).Select(x => x).ToList();
        }
    }

嗯。。。真的很奇怪。 您是否有mscorlib的参考资料和系统使用?
也许您还有另一个名为DateTime的类,它会覆盖System.DateTime

这是在声明捕获的变量范围的上下文中移动执行点的副作用。将其报告为IDE错误是合理的,但修复它并不是一件小事。基本上,
date
不是一个变量-它是捕获上下文中的一个字段,因为lambda。编译器基本上执行以下操作:

if (!filteredColl.Any())
{
    var ctx = new SomeCaptureContext(); // <== invented by the compiler
    ctx.date = new DateTime();

    filteredColl = coll.Where(ctx.SomePredicate).Select(x => x).ToList();
}
这里的问题是,当您将执行位置拖动到:

DateTime? date = new DateTime();
实际上,您正在(以IL术语)将其拖动到行:

ctx.date = new DateTime();
紧靠该行之前的捕获上下文行,即

var ctx = new SomeCaptureContext();
从未执行过,因此
ctx
null
。因此出现了
NullReferenceException


将此记录为bug是合理的,但这是一个很微妙的bug—您不一定总是希望拖动执行上下文来初始化捕获上下文—它必须是“如果它们是
null

,这很奇怪。这一行不应该抛出任何
NullReferenceException
。我可以在没有NRE的情况下编译您的完整代码。我创建了一个全新的控制台项目,在那里添加了代码,当我执行上述步骤时,它仍然崩溃。这是一个.NETFramework4.5项目。我用堆栈跟踪更新了文章。Visual Studio 2012可能有问题?是否正在尝试调试发布版本?您的解释很好,但是如果(!filteredColl.Any())将执行点拖到
下的左括号中,您仍然会遇到相同的异常。范围不应该在括号后面声明吗?
ctx.date = new DateTime();
var ctx = new SomeCaptureContext();