【发布时间】:2011-02-01 20:06:42
【问题描述】:
最近我的同事向我展示了一段无法正常工作的代码:
public class SomeClass
{
private IList<Category> _categories;
public void SetCategories()
{
_categories = GetCategories() ?? new List<Category>();
DoSomethingElse();
}
public IList<Category> GetCategories()
{
return RetrieveCategories().Select(Something).ToList();
}
}
(我知道运算符是多余的,因为 linq ToList 将始终返回一个列表,但这就是代码的设置方式)。
问题在于 _categories 为 null。在调试器中,在_categories = GetCategories() ?? new List<Category>() 上设置断点,然后单步执行 DoSomethingElse(),_categories 仍然为空。
直接将 _categories 设置为 GetCategories() 效果很好。拆分??进入完整的 if 语句工作正常。空合并运算符没有。
这是一个 ASP.NET 应用程序,因此可能有不同的线程在干扰,但它在他的机器上,只有他连接在浏览器中。 _cateogories 不是静态的,或者任何东西。
我想知道的是,这怎么可能发生?
编辑:
更奇怪的是,_categories 从未在该函数之外的任何地方设置(除了初始化类)。
具体代码如下:
public class CategoryListControl
{
private ICategoryRepository _repo;
private IList<Category> _categories;
public override string Render(/* args */)
{
_repo = ServiceLocator.Get<ICategoryRepository>();
Category category = _repo.FindByUrl(url);
_categories = _repo.GetChildren(category) ?? new List<Category>();
Render(/* Some other rendering stuff */);
}
}
public class CategoryRepository : ICategoryRepository
{
private static IList<Category> _categories;
public IList<Category> GetChildren(Category parent)
{
return _categories.Where(c => c.Parent == parent).ToList<Category>();
}
}
即使 GetChildren 神奇地返回了 null,CategoryListControl._categories 仍然永远不应该为 null。 GetChildren 也不应该因为 IEnumerable.ToList() 而返回 null。
编辑 2:
试用@smartcaveman 的代码,我发现了这个:
Category category = _repo.FindByUrl(url);
_categories = _repo.GetChildren(category) ?? new List<Category>();
_skins = skin; // When the debugger is here, _categories is null
Renderer.Render(output, _skins.Content, WriteContent); // When the debugger is here, _categories is fine.
同样,在测试if(_categories == null) throw new Exception() 时,if 语句中的_categories 为空,因此没有抛出异常。
所以,这似乎是一个调试器错误。
【问题讨论】:
-
是不是因为你在语句中实例化了?可能很好,但我以前没有这样用过。
-
你能再检查一下吗?我在想“调试错误”。
-
这里引人入胜的部分是
GetCategories()无论如何都无法返回null。无论如何,合并运算符是没有用的。 -
刚刚找到this topic。
-
@Pieter:是的,他知道。