[英]Why the following C# code throws NullReferenceException on nullable DateTime initialization?
这是一些简单的代码:
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();
}
}
问题是, 为什么以下步骤使其与NullReferenceException崩溃 :
1)断点到if
2)设置下一个执行点:
3)尝试继续使用F10:
如果我注释掉代码的最后一行,它就不会崩溃。
更新:这是堆栈跟踪:
System.NullReferenceException was unhandled HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=ConsoleApplication28 StackTrace:
at ConsoleApplication28.Program.Main(String[] args) in Program.cs: line 21
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException:
这是在声明捕获的变量范围的上下文中移动执行点的副作用。 将其报告为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();
}
SomePredicate
是:
class SomeCaptureContext {
public DateTime? date; // yes, a public field - needs to support 'ref' etc
public bool SomePredicate(string x) // the actual name is horrible
{
return this.date.GetValueOrDefault()
.Date.ToString(CultureInfo.InvariantCulture) == x;
}
}
这里的问题是当您将执行位置拖动到:
DateTime? date = new DateTime();
您实际上 (以IL术语)将其拖动到该行:
ctx.date = new DateTime();
紧接着之前的捕获上下文行,即
var ctx = new SomeCaptureContext();
从未执行过,所以ctx
为null
。 因此NullReferenceException
。
将此作为一个错误记录是合理的,但它是一个微妙的 - 你不一定总是想要拖动执行上下文来初始化捕获上下文 - 它必须是“如果它们为null
”。
嗯......真的很奇怪。 你有引用中的mscorlib和使用中的系统吗? 也许你有一个名为DateTime的另一个类,它会覆盖System.DateTime。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.