19

Typeクラスのジェネリック型に「ユーザーフレンドリーな」名前を付ける再帰メソッドを作成せずに簡単な方法はありますか?

たとえば、次のコードでは、次のコードで指定された省略形または完全な名前ではなく、'List<Dictionary<Int>>' のようなものが必要です。

var list = new List<Dictionary<int, string>>();
var type = list.GetType();

Console.WriteLine(type.Name);
Console.WriteLine(type.FullName);
4

5 に答える 5

38

編集した質問に基づいて、次のようなものが必要です。

public static string GetFriendlyName(this Type type)
{
    if (type == typeof(int))
        return "int";
    else if (type == typeof(short))
        return "short";
    else if (type == typeof(byte))
        return "byte";
    else if (type == typeof(bool)) 
        return "bool";
    else if (type == typeof(long))
        return "long";
    else if (type == typeof(float))
        return "float";
    else if (type == typeof(double))
        return "double";
    else if (type == typeof(decimal))
        return "decimal";
    else if (type == typeof(string))
        return "string";
    else if (type.IsGenericType)
        return type.Name.Split('`')[0] + "<" + string.Join(", ", type.GetGenericArguments().Select(x => GetFriendlyName(x)).ToArray()) + ">";
    else
        return type.Name;
}
于 2013-05-09T16:19:51.863 に答える
15

すでに提供されている再帰メソッドを呼び出すことで、再帰メソッドの作成を回避できます。

static string GetTypeName(Type type)
{
    var codeDomProvider = CodeDomProvider.CreateProvider("C#");
    var typeReferenceExpression = new CodeTypeReferenceExpression(new CodeTypeReference(type));
    using (var writer = new StringWriter())
    {
        codeDomProvider.GenerateCodeFromExpression(typeReferenceExpression, writer, new CodeGeneratorOptions());
        return writer.GetStringBuilder().ToString();
    }
}

これには型の名前空間が含まれますが、アセンブリ参照は除外されることに注意してください。質問のタイプの場合、結果は次のようになります。

System.Collections.Generic.List<System.Collections.Generic.Dictionary<int, string>>

それが「何かのようなもの」に該当するかどうかは私には明らかではありませんList<Dictionary<int, string>>

于 2013-05-09T16:45:36.430 に答える
0

リフレクション - System.Type インスタンスからジェネリック パラメータを取得する

ジェネリック型でリフレクションを使用することもできます。

var dict = new Dictionary<string, int>();

    Type type = dict.GetType();
    Console.WriteLine("Type arguments:");
    foreach (Type arg in type.GetGenericArguments())
    {
        Console.WriteLine("  {0}", arg);
    }

その後、それをオブジェクトの拡張メソッドに入れて、必要な場所で使用できます。また、すべての再帰は命令コードとして記述できることも付け加えておきます。

したがって、コード全体は次のようになります。

 static void GetGenericParametersNames(Type type)
        {
            Queue<Type> typeQueue = new Queue<Type>();
            typeQueue.Enqueue(type);
            while (typeQueue.Any())
            {
                var t = typeQueue.Dequeue();
                Console.WriteLine("  {0}", arg);

                foreach (Type arg in t.GetGenericArguments())
                {
                    typeQueue.Enqueue(t);
                }
            }
        }
于 2013-05-09T16:34:06.783 に答える