Что означает «апостроф + число» в типе объекта свойств с дженериками (например, «Collection`1»)? - PullRequest
10 голосов
/ 05 июля 2011

У меня есть объект (MyObject) со свойством (MyProperty).Я хочу получить его имя типа (например, String или MyClass и т. Д.).Я использую:

PropertyInfo propInfo = typeof(MyObject).GetProperty("MyProperty");
Console.WriteLine(propInfo.PropertyType.Name);
Console.WriteLine(propInfo.PropertyType.FullName);

Нет проблем с простыми типами, но когда MyProperty является универсальным типом, я сталкиваюсь с проблемами при получении его имени (например, Collection<String>).Он печатает:

Коллекция`1

System.Collections.ObjectModel.Collection`1 [[System.String, mscorlib, Версия = 2.0.0.0, Культура = нейтральная, PublicKeyToken =b77a5c561934e089]]

Что это такое `1?И как я могу получить "Collection<String>"?

Ответы [ 3 ]

11 голосов
/ 05 июля 2011

`` 1` означает универсальный тип с 1 универсальным параметром.

Одним из способов получения строки является использование System.CodeDom , как предлагает @ LukeH :

using System;
using System.CodeDom;
using System.Collections.Generic;
using Microsoft.CSharp;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var p = new CSharpCodeProvider())
            {
                var r = new CodeTypeReference(typeof(Dictionary<string, int>));

                Console.WriteLine(p.GetTypeOutput(r));
            }
        }
    }
}

Альтернативный метод здесь . Ниже приведен код @ jaredpar :

public static string GetFriendlyTypeName(Type type) {
    if (type.IsGenericParameter)
    {
        return type.Name;
    }

    if (!type.IsGenericType)
    {
        return type.FullName;
    }

    var builder = new System.Text.StringBuilder();
    var name = type.Name;
    var index = name.IndexOf("`");
    builder.AppendFormat("{0}.{1}", type.Namespace, name.Substring(0, index));
    builder.Append('<');
    var first = true;
    foreach (var arg in type.GetGenericArguments())
    {
        if (!first)
        {
            builder.Append(',');
        }
        builder.Append(GetFriendlyTypeName(arg));
        first = false;
    }
    builder.Append('>');
    return builder.ToString();
}
8 голосов
/ 05 июля 2011

Это внутреннее имя CLR.

Число - это число параметров универсального типа, поскольку типы могут быть перегружены.
(Func`1 и Func`2 - это разные типы)

Не существует встроенного способа получить имя типа в стиле C #, поскольку CLR не имеет ничего общего с C #.

0 голосов
/ 05 июля 2011

SLaks уже объяснил, что означает `1.

О вашем втором вопросе: Вы можете получить имя параметров универсального типа, используя Type.GetGenericArguments :

if (propInfo.PropertyType.IsGenericType) {
    Type[] typeArguments = propInfo.PropertyType.GetGenericArguments();
    // typeArguments now contains an array of types ({String} in your example).
}
...