为什么下面的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();