File: System\Runtime\Serialization\BinaryFormat\Utils\TypeExtensions.cs
Web Access
Project: src\src\libraries\System.Runtime.Serialization.BinaryFormat\src\System.Runtime.Serialization.BinaryFormat.csproj (System.Runtime.Serialization.BinaryFormat)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
 
namespace System.Runtime.Serialization.BinaryFormat.Utils;
 
internal static class TypeExtensions
{
    internal static string GetAssemblyNameIncludingTypeForwards(this Type type)
    {
        // Special case types like arrays
        Type attributedType = type;
        while (attributedType.HasElementType)
        {
            attributedType = attributedType.GetElementType()!;
        }
 
        foreach (Attribute first in attributedType.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false))
        {
            return ((TypeForwardedFromAttribute)first).AssemblyFullName;
        }
 
        return type.Assembly.FullName!;
    }
 
    internal static string GetTypeFullNameIncludingTypeForwards(this Type type)
    {
        return type.IsArray ?
            GetClrTypeFullNameForArray(type) :
            GetClrTypeFullNameForNonArrayTypes(type);
    }
 
    private static string GetClrTypeFullNameForArray(Type type)
    {
        int rank = type.GetArrayRank();
 
        string typeName = GetTypeFullNameIncludingTypeForwards(type.GetElementType()!);
        return rank == 1 ?
            typeName + "[]" :
            typeName + "[" + new string(',', rank - 1) + "]";
    }
 
    private static string GetClrTypeFullNameForNonArrayTypes(Type type)
    {
        if (!type.IsGenericType)
        {
            return type.FullName!;
        }
 
        var builder = new StringBuilder(type.GetGenericTypeDefinition().FullName).Append('[');
 
        foreach (Type genericArgument in type.GetGenericArguments())
        {
            builder.Append('[').Append(GetTypeFullNameIncludingTypeForwards(genericArgument)).Append(", ");
            builder.Append(GetAssemblyNameIncludingTypeForwards(genericArgument)).Append("],");
        }
 
        // Replace the last comma with a close bracket
        Debug.Assert(builder[builder.Length - 1] == ',');
        builder[builder.Length - 1] = ']';
 
        return builder.ToString();
    }
}