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

C#中值类型数组转IEnumerable<object>失败问题咨询

问题解答

1. 原代码失效的原因

  • .NET 中泛型协变仅支持引用类型,值类型数组(如short[]、double[])无法隐式转换为IEnumerable<object>。虽然单个值类型实例可以装箱为object,但值类型数组本身实现的是IEnumerable<[值类型]>(比如short[]实现IEnumerable<short>),而非IEnumerable<object>,因此tmpobj is IEnumerable<object>的判断会返回false。
  • 判断失败后,代码会执行tmpobj.ToString(),对于数组来说,这会返回数组的类型名称(如System.Int16[]),而非遍历元素写入集合,这就是异常行为的根源。

2. 代码修改方案

核心思路是改用**非泛型的IEnumerable**进行判断(所有数组和可枚举类型都实现了这个接口),同时排除字符串(避免把字符串拆成单个字符遍历)。修改后的代码如下:

ManagementObjectCollection searchResults = new ManagementObjectSearcher(
        "select * from " + key).Get(); // 测试用例:"Win32_ComputerSystem"
int counter = 0;
foreach (ManagementBaseObject? searchResult in searchResults) {
    if (searchResult is null)
        continue;

    counter += 1;
    foreach (PropertyData? property in searchResult.Properties) {
        if (property.Name is null) {
            continue;
        }

        object tmpobj = searchResult.GetPropertyValue(property.Name);
        string propertyname = $"{counter} | {property.Name}";
        if (tmpobj is null) {
            continue;
        }
        
        // 先排除字符串,再判断是否为非泛型可枚举类型
        if (tmpobj is not string && tmpobj is IEnumerable tmpcollection) {
            foreach (object item in tmpcollection) {
                descriptor.Properties.Add(propertyname, item?.ToString());
            }
        }
        else {
            descriptor.Properties.Add(propertyname, tmpobj.ToString());
        }
    }
}

关键修改点:

  • 替换IEnumerable<object>为非泛型IEnumerable,覆盖所有可枚举类型(包括值类型数组)。
  • 增加tmpobj is not string判断,避免误将字符串当作可枚举集合遍历字符。
  • 用item?.ToString()简化空值处理,替代嵌套的空值检查逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:45:58