c# - foreach 循环变量抛出 NullReferenceException 但 Enumerable 不为空
问题描述
有些人决定关闭我之前的问题,但他们链接的问题(什么是 NullReferenceException,以及如何解决它?)没有答案。这个问题是根本不同的,因为枚举是填充的。它不为空。正如第一个答案所说,我放置了“战略断点”并检查了变量。
我正在调试 XUnit 测试,结果发现在我的业务逻辑中,foreach 循环中的迭代变量引发了异常“对象引用未设置为对象实例”。但是,发生迭代的列表不为空。我在调试时可以看到。这是代码:
商业逻辑:
List<string> regionArray = new List<string>();
if (someCondition)
{
regionArray = _utils.GetRegions(someParam); // this is not returning null
}
foreach (var region in regionArray)
{
var query = from dataSet in myDataSets
where dataSet.Location == region
select dataSet;
var queryResult = query.FirstOrDefault();
if (queryResult == null)
{
// do stuff
} else if (queryResult.State != States.Provisioned)
{
// do stuff
}
}
这是我嘲笑_utils.GetRegions
电话的方式,但我认为这不是问题所在。
private Mock<IUtils> _mockRegionUtils;
[Fact]
public void ItWorks()
{
// do stuff
_mockRegionUtils = new Mock<IUtils>();
_mockRegionUtils.Setup(utils => utils.GetRegions(It.IsAny<ISomeParam>())).Returns(new List<string>() {"america", "china"});
// call business logic
}
我已经检查了调试器中的所有类型。regionArray.GetType()
返回{System.Collections.Generic.List`1[System.String]}
。但是,当我在控制台中键入区域时,我得到:
region
'region' threw an exception of type 'System.NullReferenceException'
这怎么可能?
编辑:修正了上面的错字,对此感到抱歉。不过有些奇怪,所以如果我将值重新分配为regionArray
内联列表,它仍然会失败。但是,如果我定义一个新的内联列表并对其进行迭代,则循环工作正常。
List<string> regionArray = new List<string>();
if (someCondition)
{
regionArray = _utils.GetRegions(someParam); // this is not returning null
}
regionArray = new List<string>() {"china", "america"};
List<string> temp = new List<string>() {"foo", "bar"}
foreach (var region in regionArray)
{
// region still throws null reference exception
foreach (var tempVar in temp)
{
var c = tempVar; // this works. tempvar is never null.
}
var query = from dataSet in myDataSets
where dataSet.Location == region
select dataSet;
var queryResult = query.FirstOrDefault();
if (queryResult == null)
{
// do stuff
} else if (queryResult.State != States.Provisioned)
{
// do stuff
}
}
regionArray
编辑2:所以我尝试在上面的逻辑之前以相同的方式迭代,它工作得很好。
List<string> regionArray = new List<string>();
if (someCondition)
{
regionArray = _utils.GetRegions(someParam); // this is not returning null
}
foreach (var region in regionArray)
{
var c = region; // this works
}
foreach (var region in regionArray)
{
// region throws null reference exception
var query = from dataSet in myDataSets
where dataSet.Location == region
select dataSet;
var queryResult = query.FirstOrDefault();
if (queryResult == null)
{
// do stuff
} else if (queryResult.State != States.Provisioned)
{
// do stuff
}
}
所以最有可能的是,起订量对象不是问题。根据@Iliar 的建议,我会看看是否regionArray
被修改,但乍一看,因为 regionArray 没有在循环中使用,我的回答是“否”。
解决方案
更新:我通过将region
循环变量重命名为不同的名称来解决这个问题。事实证明,我foreach (var region ...)
在代码的前面做了另一个循环。我与一些高级同事讨论了为什么这两个名称会相互冲突,他们说这可能是 VSCode 中的符号有问题,而不是我的实际代码。谢谢大家的帮助!
这个线程中有很多信息,所以在这里总结一下是一些要点,以防将来对其他人有帮助:
在调试 XUnit 测试时,我看到我的 foreach 中的循环变量在 tooltip 中显示以下信息
'region' threw an exception of type 'System.NullReferenceException' Data [IDictionary]:{System.Collections.ListDictionaryInternal} HResult [int]:-2147467261 HelpLink [string]:null InnerException [Exception]:null Message [string]:"Object reference not set to an instance of an object." Source [string]:"9dd66c33104045bba27ad3fc9fb95185" StackTrace [string]:" at <>x.<>m0(<IngestEvents>d__13 <>4__this)" TargetSite [MethodBase]:{System.String <>m0(<IngestEvents>d__13)} Static members ...
。即使我进入循环,工具提示
region
仍然显示上述内容,当我输入region
控制台时,我得到了'region' threw an exception of type 'System.NullReferenceException'.
以上两点让我相信
region
是空的。但是,通过@IVSoftware 的帮助,我验证了它region
实际上不是空的,因为断言正在通过。- 然后我查看了我的其余代码,作为随机猜测,我尝试将循环变量重命名
region
为其他内容。当我这样做时,region
被正确设置为列表的元素。
推荐阅读
- apache - LiteSpeed(或 apache)重写以从 mirror.com 中隐藏 SUBFOLDERS domain.com 和 www.domain.com
- macos - 在 Swift 中获取有关显卡的信息
- swift - 从 TableView 标头访问 UITableViewController 委托
- c# - 无论点数如何,如何在二维网格上形成一个盒子
- neo4j - Cypher:避免在多个关系路径中循环
- java - Spring Cloud Gateway 超出缓冲区的最大字节数限制:262144 错误
- javascript - 用js改变contenteditable值
- typescript - 如何在 Typescript 中访问可能的空对象的对象属性?
- swift - WatchOS 'UIBackgroundModes'
- vue.js - Vue3 jgile / vue-csv-import 保存映射/注入映射