コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【C#】ジェネリック型の名前を「Dictionary`2」ではなく「Dictionary<int, string>」という形式で取得する方法

ソースコード

using System;
using System.Linq;

namespace Kogane
{
    public static class TypeUtils
    {
        // https://stackoverflow.com/questions/1533115/get-generictype-name-in-good-format-using-reflection-on-c-sharp
        public static string GetPrettyName( Type type )
        {
            if ( type.IsArray )
            {
                return $"{GetPrettyName( type.GetElementType() )}[]";
            }

            if ( type.IsGenericType )
            {
                var typeName              = type.Name;
                var simpleTypeName        = typeName.Substring( 0, typeName.LastIndexOf( "`", StringComparison.InvariantCulture ) );
                var genericArgumentsNames = string.Join( ", ", type.GetGenericArguments().Select( x => GetPrettyName( x ) ) );

                return $"{simpleTypeName}<{genericArgumentsNames}>";
            }

            return GetCSharpTypeKeyword( type );
        }

        public static string GetCSharpTypeKeyword( Type type )
        {
            return GetCSharpTypeKeyword( type.Name );
        }

        // https://stackoverflow.com/questions/56352299/gettype-return-int-instead-of-system-int32
        // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
        public static string GetCSharpTypeKeyword( string typeName )
        {
            return typeName switch
            {
                "Boolean" => "bool",
                "Byte"    => "byte",
                "SByte"   => "sbyte",
                "Char"    => "char",
                "Decimal" => "decimal",
                "Double"  => "double",
                "Single"  => "float",
                "Int32"   => "int",
                "UInt32"  => "uint",
                "Int64"   => "long",
                "UInt64"  => "ulong",
                "Int16"   => "short",
                "UInt16"  => "ushort",
                "Object"  => "object",
                "String"  => "string",
                "Void"    => "void",
                _         => typeName,
            };
        }
    }
}

通常

Debug.Log( typeof( List<int> ).Name );               // List`1
Debug.Log( typeof( Dictionary<int, string> ).Name ); // Dictionary`2

使用例

Debug.Log( TypeUtils.GetPrettyName( typeof( List<int> ) ) );               // List<int>
Debug.Log( TypeUtils.GetPrettyName( typeof( Dictionary<int, string> ) ) ); // Dictionary<int, string>