Отримайте ім'я типу без повного простору імен


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
Це має бути прийнятою відповіддю, оскільки вона належним чином враховує загальні типи, які можуть повторюватися (наприклад, словник <int?, Int?>).
Отіс

+1 для концепції. Але не подобається невдала передчасна оптимізація. Він створює нове StringBuilder в кожному рекурсивному виклику (навіть базовий випадок, коли він не використовується), але ігнорує string.Joinтимчасовий і LINQ лямбда. Просто використовуйте, Stringпоки не дізнаєтесь, що це вузьке місце. / rant
Nigel Touch

1
Найджел, там написано, що це, мабуть, не найкраще рішення :)
gregsdennis

ShortName - скорочена назва :)
Валера



5

Після C # 6.0 (у тому числі) ви можете використовувати nameof вираз:

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", тоді як фактичним об'єктом може бути "Список".


3
nameofне повертає ім'яType
Nigel Touch

@NigelTouch Я перевірив і поверну nameofім’я Type, скріншот із підтвердженням: prntscr.com/irfk2c
Stas Boyarincev

1
Вибачте, я не пояснив добре. Я маю на увазі те, що він не отримує час виконання базового об'єкта Type, це лише аргумент часу компіляції. Якщо метод приймає, IEnumerableтоді nameofпросто повертає "IEnumerable", тоді як фактичним об'єктом може бути "Список <рядок>". Не думаю, що це відповідає на питання ОП.
Nigel Touch

-2

найкращий спосіб використання:

obj.GetType().BaseType.Name

1
Будь ласка, надайте пояснення до своєї відповіді, щоб зробити її більш зрозумілою для інших користувачів.
Станіслав Мехоношин

Одного разу я знайшов "GetType (). Ім'я", просто написаний таким чином всередині віртуальної функції. Хтось може мені пояснити, чому він не має obj.GetType (). BaseType.Name? Я вчуся. Я розумію мету, але не всі деталі синтаксису. Дякую.
Дієго Ореллана

Що стосується базового типу?
johnny 5

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