最近我的同事向我展示了一系列无法正常工作的代码:
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是空的.在调试器中,在_categories = GetCategories()?上设置断点新列表< Category>(),然后转到DoSomethingElse(),_categories仍然为null.
直接设置_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也应该永远不会返回null因为IEnumerable.ToList().
编辑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)抛出新的Exception()时,_categories在if语句上为空,则不会抛出异常.
所以,这似乎是一个调试器的bug.
解决方法
这可能是调试器的问题,而不是代码.尝试在使用合并运算符的语句之后打印值或进行空检查.