Recently my co-worker showed me a block of code that was not working correctly:
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();
}
}
(I am aware that the operator is superfluous since the linq ToList will always return a list, but that is how the code was set up).
The problem was that _categories was null. In the debugger, setting a breakpoint on _categories = GetCategories() ?? new List<Category>()
, then stepping over to DoSomethingElse(), _categories would still be null.
Directly setting _categories to GetCategories() worked fine. Splitting the ?? in to a full if statement worked fine. The null coalescing operator did not.
It is an ASP.NET application, so a different thread could possibly be interfering, but it was on his machine, with only him connected in a browser. _cateogories is not static, or anything.
What I'm wondering is, how could this possibly happen?
Edit:
Just to add to the bizarreness, _categories
is never set anywhere besides that function (apart from initializing the class).
The exact code is like so:
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>();
}
}
Even it GetChildren magically returned null, CategoryListControl._categories still should never, ever be null. GetChildren should also never, ever return null because of IEnumerable.ToList().
Edit 2:
Trying out @smartcaveman's code, I found out this:
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.
As well, when testing if(_categories == null) throw new Exception()
, _categories was null on the if statement, then stepping over the exception was not thrown.
So, it seems like this is a debugger bug.
This could be a problem with the debugger rather than with the code. Trying printing out the value or doing a null check after the statement with the coalesce operator.
The null-coalescing operator is not broken. I use it in a similar manner all the time quite successfully. Something else is going on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With