Pet*_*r82 2 .net c# ienumerable nullreferenceexception
看一下这段代码:
var categories = tokens.SelectMany(x => x.Categories);
if (categories != null)
{
if (categories.Contains("interp")) //null ref exception
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试在类别中查找“interp”字符串时,出现空引用异常。所以看来“类别!= null”不起作用。
我找到了一些建议(这里How to check if IEnumerable is null orempty?),但它们涉及使用.Any()。但它只会使异常更早地准确(使用 .Any() 时)。甚至 ?.Any() 也会引发异常。
有任何想法吗?
categories.Contains仅当 Categories属性为 null 时,此代码才会抛出 NRE 。
以下代码将抛出:
class Token
{
public string[] Categories{get;set;}
}
var tokens=new []{new Token()};
var categories = tokens.SelectMany(x => x.Categories);
if (categories != null)
{
if (categories.Contains("interp"))
{
Console.WriteLine("Found");
}
}
Run Code Online (Sandbox Code Playgroud)
但也会如此
tokens.SelectMany(x => x.Categories).ToArray();
Run Code Online (Sandbox Code Playgroud)
实际抛出的是SelectMany 内的嵌套迭代器,而不是ToArray()or Contains。该异常的堆栈跟踪是:
at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
at UserQuery.Main()
Run Code Online (Sandbox Code Playgroud)
SelectMany将尝试迭代每个Categories条目,发现该属性实际上为 null 并抛出。
Where快速解决方法是在前面添加一个SelectMany以消除空类别:
var categories = tokens.Where(x=>x.Categories!=null).SelectMany(x => x.Categories);
Run Code Online (Sandbox Code Playgroud)
真正的解决方案是确保Categories永远不会为空 - 它应该在构造时初始化为空数组、列表等。重新分配时,绝不应将其设置为 null。
此示例将该_categories字段设置为,new string[0]即使调用者传递null到“类别”
class Token
{
string[] _categories=new string[0];
public string[] Categories{
get => _categories;
set => _categories = value??new string[0];
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,Where(x=>x.Categories !=null)就不再需要了
| 归档时间: |
|
| 查看次数: |
986 次 |
| 最近记录: |