Як отримати ім’я типу загального аргументу типу?


99

Якщо у мене є такий підпис методу, як

public string myMethod<T>( ... )

Як я можу всередині методу отримати назву типу, який був заданий як аргумент типу? Я хотів би зробити щось подібне typeof(T).FullName, але це насправді працює ...


10
typeof(T).FullName повинен працювати. Що відбувається натомість?
Натан Тейлор,

Я отримав помилки компілятора в цьому твердженні - але, очевидно, вони були викликані чимось іншим, тому що зараз він працює. Дякую!
Томаш Ашан

Відповіді:


156

Ваш код повинен працювати. typeof(T).FullNameцілком справедливий. Це повністю складна, функціонуюча програма:

using System;

class Program 
{
    public static string MyMethod<T>()
    {
        return typeof(T).FullName;
    }

    static void Main(string[] args)
    {
        Console.WriteLine(MyMethod<int>());

        Console.ReadKey();
    }

}

Виконання вищезгаданих відбитків (як очікувалося):

System.Int32

Переконайтесь, що протестуйте його за допомогою MyMethod <int>> () і подивіться, що ви отримаєте ... вам доведеться враховувати нульові типи, якщо ви дбаєте про базовий тип у цьому сценарії.
GR7

1
Ви маєте на увазі " <int?>" Якщо так, це працює, але ви отримуєте System.Nullable<int>(у синтаксисі повного імені), саме цього ви і очікували ...
Рід Копсі

Незважаючи на те, що у мене вже було рішення (хоча воно чомусь не спрацювало ...), я надам тобі відповіді за написання найкращої відповіді на сьогоднішній день =)
Томаш Ашан

1
Це як раз допоміг мені , так як я припускав , що nameof(T)і typeof(T).Nameбуде робити те ж саме. Виходить nameof(T)просто повертається T.
дахвід

5

typeof(T).Nameі typeof(T).FullNameпрацюють на мене. Я отримую тип переданий як аргумент.


1
ах. Якщо тип, який ви передали, має значення Nullable, для отримання базового типу вам доведеться використовувати щось на зразок typeof (T) .GetGenericArguments () [0]
GR7,

щоб перевірити, чи є тип недійсним, ви використовуєте typeof (T) .IsGenericType, і якщо він є, ви використовуєте наступне для отримання типу Name (Ім'я) або FUllName ((Type) .GetGenericArguments () [0 ])
.Ім'я

1

Якщо припустити, що у вас є якийсь екземпляр T, він не відрізняється від будь-якого іншого типу.

var t = new T();

var name = t.GetType().FullName;

2
Вам навіть не потрібен екземпляр T .... typeof (T) чудово працює без екземпляра ... Ваш надасть іншу поведінку, якщо в метод буде передано підклас (як аргумент) ..
Рід Копсі

1
Проблема з цим кодом полягає в тому, що якщо T не має конструктора без параметрів, він не працюватиме.
Натан Тейлор

@Nathan - це був лише приклад показати, як отримати екземпляр T. Імовірно, на загальному методі у нього буде доступний якийсь тип T. @Reed - ти, звичайно, маєш рацію, я припустив, що це він був після.
утроба

Інша проблема буде в тому випадку, якщо T - абстрактний клас або інтерфейс - вищевказаний код не працює. У випадку, якщо існує загальне обмеження типу ("де"), цей тип коду може бути безпечним, оскільки ми знаємо конструктор і може насправді мати підстави інстанціювати тип. Крім цієї інстанції, це марно.
Андрій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.