【发布时间】:2013-10-21 12:57:51
【问题描述】:
当我运行此代码时,我得到了一个意外的 NullReferenceException,省略了 fileSystemHelper 参数(因此默认为 null):
public class GitLog
{
FileSystemHelper fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="GitLog" /> class.
/// </summary>
/// <param name="pathToWorkingCopy">The path to a Git working copy.</param>
/// <param name="fileSystemHelper">A helper class that provides file system services (optional).</param>
/// <exception cref="ArgumentException">Thrown if the path is invalid.</exception>
/// <exception cref="InvalidOperationException">Thrown if there is no Git repository at the specified path.</exception>
public GitLog(string pathToWorkingCopy, FileSystemHelper fileSystemHelper = null)
{
this.fileSystem = fileSystemHelper ?? new FileSystemHelper();
string fullPath = fileSystem.GetFullPath(pathToWorkingCopy); // ArgumentException if path invalid.
if (!fileSystem.DirectoryExists(fullPath))
throw new ArgumentException("The specified working copy directory does not exist.");
GitWorkingCopyPath = pathToWorkingCopy;
string git = fileSystem.PathCombine(fullPath, ".git");
if (!fileSystem.DirectoryExists(git))
{
throw new InvalidOperationException(
"There does not appear to be a Git repository at the specified location.");
}
}
当我在调试器中单步执行代码时,在我跨过第一行(使用 ?? 运算符)之后,fileSystem 的值仍然为 null,如此屏幕截图所示(跨过下一行抛出NullReferenceException):
这不是我所期望的!我期待空合并运算符发现参数为空并创建一个new FileSystemHelper()。我已经盯着这段代码看了很久,看不出它有什么问题。
ReSharper 指出该字段仅用于这一种方法,因此可能会转换为局部变量...所以我尝试了,猜猜是什么?有效。所以,我有我的解决方法,但我无法终生明白为什么上面的代码不起作用。我觉得我正在学习一些关于 C# 的有趣的东西,或者我做了一些非常愚蠢的事情。谁能看到这里发生了什么?
【问题讨论】:
-
您已经在方法参数中声明
fileSystemHelper是null,我不确定,但这可能与它有关。但话又说回来,我猜。 -
您确定 NRE 不会发生在 within GetFullPath(忽略手表显示的内容)吗?我看不出上面的代码会导致上述行为。
-
好的,从 VisualStudio 退出去做其他事情然后重新加载它,现在一切正常,我无法重现问题。我认为这可能是 ReSharper 单元测试运行程序的一个奇怪的缓存问题。我正在使用一个简单的 MSpec 测试来练习代码。 ReSharper 在运行单元测试时会获取程序集的卷影副本,有时,只是有时,卷影副本似乎“卡住”了,我以前见过几次。所以很可能,我实际上是在运行旧代码,即使我已经手动重建了所有内容。这是我最好的解释......
标签: c# null-coalescing-operator