You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Visual Studio测试资源管理器运行测试时遇System.InvalidOperationException错误

解决"Sequence contains more than one matching element"异常问题

这个问题我之前排查过,核心是你对SingleOrDefault的行为理解有偏差!

为什么会报错?

SingleOrDefault的设计逻辑是:

  • 序列里0个匹配元素:返回null
  • 序列里1个匹配元素:返回该元素
  • 序列里多个匹配元素:直接抛出InvalidOperationException——这就是你看到的报错

你的测试数据里,肯定存在多个name属性(忽略大小写后)和settingName相同的XElement,触发了这个校验逻辑。

两种解决方案,看你需求选:

方案1:只需要任意一个匹配的设置(最常用,快速解决)

如果你的场景允许存在重复设置,只需要取第一个匹配的元素,把SingleOrDefault换成FirstOrDefault就行。FirstOrDefault会返回第一个匹配的元素,没有匹配就返回null,完全符合你原代码的预期逻辑:

private static string ParseSetting(List<XElement> settings, string settingName)
{
    return settings
        .FirstOrDefault(s => s.Attribute("name")?.Value.ToLower() == settingName.ToLower())
        ?.Attribute("value")?.Value;
}

方案2:需要校验重复(保留原逻辑的严谨性)

如果你的业务不允许存在重复的设置,想要保留“检查重复”的逻辑,但不想直接抛出系统异常,可以自己手动处理重复情况——比如抛自定义异常、打警告日志,或者明确取第一个:

private static string ParseSetting(List<XElement> settings, string settingName)
{
    var lowerCaseSettingName = settingName.ToLower();
    var matchedSettings = settings
        .Where(s => s.Attribute("name")?.Value.ToLower() == lowerCaseSettingName)
        .ToList();

    if (matchedSettings.Count > 1)
    {
        // 这里可以根据业务需求调整:
        // 1. 抛自定义异常提示配置错误
        throw new InvalidOperationException($"检测到多个名称为'{settingName}'的配置项,请检查XML结构");
        // 2. 打警告日志并取第一个
        // Console.WriteLine($"警告:找到多个'{settingName}'配置项,将使用第一个");
        // return matchedSettings.First().Attribute("value")?.Value;
    }

    return matchedSettings.SingleOrDefault()?.Attribute("value")?.Value;
}

小优化建议

可以把settingName.ToLower()提取出来,避免每次循环都重复计算,代码更优雅的同时也能轻微提升性能。

内容的提问来源于stack exchange,提问作者RShome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:21:26