Получить имя типа без полного пространства имен


293

У меня есть следующий код:

return "[Inserted new " + typeof(T).ToString() + "]";

Но

 typeof(T).ToString()

возвращает полное имя, включая пространство имен

В любом случае можно просто получить имя класса (без квалификаторов пространства имен?)


7
Кстати, письмо string1 + anything.ToString() + string2излишне. Компилятор вставляет вызов ToStringавтоматически, если вы делаете string1 + anything + string2.
Тим Робинсон

13
не звучит грубо, но, если бы вы проверили, какие свойства доступны в Typeэкземпляре (как возвращено typeof(..)), я уверен, что вы сами это выясните ...
Питер Лиллевольд

Ответы:


530
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name

5
Nameне учитывает параметры типа.
gregsdennis

73
Или this.GetType().Name, this.GetType().FullNameи т. Д., Если иметь дело с примерами.
Авенмор

1
Nameтакже не учитывает вложенные типы!
Воинственный шимпанзе

33

Попробуйте это, чтобы получить параметры типа для универсальных типов:

public static string CSharpName(this Type type)
{
    var sb = new StringBuilder();
    var name = type.Name;
    if (!type.IsGenericType) return name;
    sb.Append(name.Substring(0, name.IndexOf('`')));
    sb.Append("<");
    sb.Append(string.Join(", ", type.GetGenericArguments()
                                    .Select(t => t.CSharpName())));
    sb.Append(">");
    return sb.ToString();
}

Возможно, не лучшее решение (из-за рекурсии), но оно работает. Выходы выглядят так:

Dictionary<String, Object>

3
Это должен быть принятый ответ, поскольку он должным образом учитывает общие типы, которые могут повторяться (например, Dictionary <int?, Int?>).
Отис

+1 за концепцию. Но не нравится неудачная преждевременная оптимизация. Он создает новый StringBuilder в каждом рекурсивном вызове (даже в базовом случае, когда он не используется), но игнорирует string.Joinвременную и LINQ-лямбду. Просто используйте, Stringпока не узнаете, что это узкое место. / rant
Найджел Тач

1
Найджел, тут же написано, что это, вероятно, не лучшее решение :)
gregsdennis

ShortName - более короткое имя :)
Валера



5

После C # 6.0 (включая) вы можете использовать nameof expression:

using Stuff = Some.Cool.Functionality  
class C {  
    static int Method1 (string x, int y) {}  
    static int Method1 (string x, string y) {}  
    int Method2 (int z) {}  
    string f<T>() => nameof(T);  
}  

var c = new C()  

nameof(C) -> "C"  
nameof(C.Method1) -> "Method1"   
nameof(C.Method2) -> "Method2"  
nameof(c.Method1) -> "Method1"   
nameof(c.Method2) -> "Method2"  
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error  
nameof(Stuff) = "Stuff"  
nameof(T) -> "T" // works inside of method but not in attributes on the method  
nameof(f) -> f  
nameof(f<T>) -> syntax error  
nameof(f<>) -> syntax error  
nameof(Method2()) -> error This expression does not have a name  

Заметка! nameofне получить базовый тип времени выполнения объекта, это просто аргумент времени компиляции. Если метод принимает IEnumerable, nameof просто возвращает «IEnumerable», тогда как фактическим объектом может быть «List».


3
nameofне возвращает имяType
Найджел Touch Touch

@NigelTouch Я проверил и nameofвернул имя Type, скриншот с доказательством: prntscr.com/irfk2c
Стас Бояринцев

1
Извините, я не очень хорошо объяснил. Я имею в виду, что он не получает время выполнения базового объекта Type, это просто аргумент времени компиляции. Если метод принимает, IEnumerableто nameofпросто возвращает «IEnumerable», тогда как фактическим объектом может быть «List <string>». Не думаю, что это отвечает на вопрос ОП.
Найджел

-2

лучший способ использовать:

obj.GetType().BaseType.Name

1
Пожалуйста, дайте некоторое объяснение вашему ответу, чтобы сделать его более понятным для других пользователей.
Станислав Мехоношин

Однажды я обнаружил, что «GetType (). Имя» просто написано внутри виртуальной функции. Может кто-нибудь объяснить мне, почему он не имеет obj.GetType (). BaseType.Name? Я учусь. Я понимаю цель, но не все детали синтаксиса. Спасибо.
Диего Орельяна

При чем тут базовый тип?
Джонни 5

Мой тест obj.GetType().BaseType.Nameвозвращается, "TypeInfo"что не является желаемым решением, как я ожидаю.
Nasenbaer
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.