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

如何在C#源代码生成器中检测数组类型并获取其元素类型?

问题描述

我正在编写一个处理模型类的C#源代码生成器,用于为类添加自定义序列化代码。模型类包含多种属性类型,当前我需要处理数组类型的属性,但无法检测这类属性:能看到属性名称和类似string[]的类型,其基类为System.Array,但无法获取元素类型。

针对集合类型,我已实现如下检测方法:

public static bool TryGetCollectionItemType(this ITypeSymbol typeSymbol, out ITypeSymbol? itemType)
{
    if (typeSymbol is INamedTypeSymbol namedType &&
        namedType.AllInterfaces
            .SingleOrDefault(i =>
                i.IsGenericType &&
                i.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)
                    .StartsWith("global::System.Collections.Generic.ICollection<"))
            is INamedTypeSymbol collectionType)
    {
        var typeArguments = namedType.TypeArguments;
        Debug.Assert(typeArguments.Length == 1);
        itemType = typeArguments[0];
        return itemType.TypeKind != TypeKind.Error;
    }
    itemType = null;
    return false;
}

我尝试按如下方式检测数组,但数组并非泛型类型,无法找到元素类型:

public static bool TryGetArrayItemType(this ITypeSymbol typeSymbol, out ITypeSymbol? itemType)
{
    if (typeSymbol is INamedTypeSymbol namedType &&
        namedType.BaseType?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) == "global::System.Array" &&
        namedType.BaseType.IsGenericType)   // it's not generic
    {
        var typeArguments = namedType.BaseType.TypeArguments;
        Debug.Assert(typeArguments.Length == 1);
        itemType = typeArguments[0];   // where can I find this instead?
        return itemType.TypeKind != TypeKind.Error;
    }
    itemType = null;
    return false;
}

请问数组类型的元素类型该从何处获取?

解决方案

数组类型在Roslyn的符号系统中对应的是**IArrayTypeSymbol**,而非INamedTypeSymbol,你需要直接判断类型符号是否实现该接口,再通过它的ElementType属性获取元素类型。

修改后的TryGetArrayItemType方法如下:

public static bool TryGetArrayItemType(this ITypeSymbol typeSymbol, out ITypeSymbol? itemType)
{
    if (typeSymbol is IArrayTypeSymbol arrayType)
    {
        itemType = arrayType.ElementType;
        return itemType.TypeKind != TypeKind.Error;
    }

    itemType = null;
    return false;
}

额外说明

  • IArrayTypeSymbol是Roslyn专门用于表示数组类型的符号接口,ElementType属性直接返回数组元素的类型符号,无需通过基类间接获取。
  • 若需处理多维数组,可通过IArrayTypeSymbol.Rank属性获取数组的维度数。

你也可以考虑将集合与数组的检测逻辑合并为一个通用方法(比如TryGetEnumerableItemType),统一处理可枚举类型的元素类型获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:35:05