2

I'm writing a source generator that processes my model classes and adds some custom serialisation code for them. The model classes can have all sorts of property types. I'm currently interested in the array properties. I cannot detect them. I see their name and the type as something like "string[]" and the base type is System.Array but I need to know the item type as well.

For collection types, the check is:

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;
}

Currently I'm trying to detect an array like this, but it doesn't seem to be generic. I can't find the item type anywhere.

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;
}

Where is the item type of the array type?

1 Answer 1

4

I found out how this can be done. The ITypeSymbol has other derivations as well, including IArrayTypeSymbol. This lets me access the item type, actually quite easily:

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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.