Как проверить, соответствует ли тип переменной типу, хранящемуся в переменной

97
User u = new User();
Type t = typeof(User);

u is User -> returns true

u is t -> compilation error

Как мне таким образом проверить, принадлежит ли переменная к какому-либо типу?

Каран
источник

Ответы:

197

Во всех остальных ответах есть существенные упущения.

isОператор не не проверить , если тип времени выполнения операнда именно данный тип; скорее, он проверяет, совместим ли тип среды выполнения с данным типом:

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

Но проверка идентичности типа с помощью отражения проверяет идентичность , а не совместимость

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false! even though x is an animal

or with the type variable
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false! even though x is an 

Если это не то, что вам нужно, то вам, вероятно, понадобится IsAssignableFrom:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true! A variable of type Animal may be assigned a Tiger.

or with the type variable
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true! A 
Эрик Липперт
источник
4
Хотя последний подход, показанный здесь, работает, он излишне многословен. typeof(Animal).IsInstanceOfType(x)короче и проще typeof(Animal).IsAssignableFrom(x.GetType());(и Resharper предложит использовать первое, если вы используете второе).
Марк Эмери
ПОЯСНЕНИЯ: ответить на исходный вопрос, заменить tна typeof(Animal). Так становится улучшенная форма Марка t.IsInstanceOfType(x).
ToolmakerSteve
13

GetType()существует для каждого типа фреймворка, потому что он определен в базовом objectтипе. Таким образом, независимо от типа, вы можете использовать его для возврата базовогоType

Итак, все, что вам нужно сделать, это:

u.GetType() == t
Дэйв Биш
источник
1
На самом деле ответ Эрика полезен и все такое, но он не отвечает на фактический вопрос о том, как тестировать с неизвестным типом в манере «u is t», описанной в исходном вопросе, и ваш ответ.
Daniel
@ Дэниел - Не совсем так. Ответ Дэйва верен, только если вы хотите исключить подклассы t. Ответ Эрика в основном объясняет, что делать; просто отсутствует пояснение, где поставить "т". Я добавлю туда комментарий.
ToolmakerSteve
10

Вам нужно увидеть, совпадает ли Тип вашего экземпляра с Типом класса. Чтобы получить тип экземпляра, вы используете GetType()метод:

 u.GetType().Equals(t);

или

 u.GetType.Equals(typeof(User));

должен это сделать. Очевидно, вы можете использовать '==' для сравнения, если хотите.

Сэм Холдер
источник
+1 Но предпочитаю второй вариант. u.GetType.Equals(typeof(User));
Омар
Одна из причин, по которой это менее безопасно, чем использование == - это то, что если GetType () каким-то образом возвращает null - он выдаст.
Дэйв Биш
1
@Fuex, да, я думаю, это упрощает чтение кода, если typeof является встроенным, поэтому я разместил его таким образом, хотя в примере OPs у него уже есть переменная, tкоторая содержит тип.
Сэм Холдер
@DaveBish, если бы GetType вернул null, я бы побеспокоился, что многие вещи начнут бросать ... но, конечно, вы правы
Сэм Холдер
@SamHolder Да - это может произойти только в том случае, если кто-то переопределит базовый тип и каким-то образом испортит реализацию. Конечно, это было бы странно.
Дэйв Биш
4

Чтобы проверить, совместим ли объект с данной переменной типа, вместо записи

u is t

ты должен написать

typeof(t).IsInstanceOfType(u)
Мантас Януленис
источник
1
В чем преимущество более подробного синтаксиса по сравнению с синтаксисом «u is t»?
Кайл Хамфельд
@KyleHumfeld Если бы у вас был Type foo; Объект А; нельзя написать «A is foo», но можно написать foo.isInstanceOfType (A)
Тимур Нуриясов