Як перевірити, чи тип змінної відповідає типу, що зберігається у змінній


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

u is User -> returns true

u is t -> compilation error

Як я можу перевірити, чи є якась змінна якогось типу таким чином?

Відповіді:


194

Всі інші відповіді містять суттєві упущення.

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 є вбудованим, саме тому я опублікував його таким чином, хоча в прикладі OP він вже має змінну, tяка містить тип.
Сем Холдер,

@DaveBish, якщо GetType повертає нуль, тоді я б переживав, що багато речей почне кидати ... але, якщо взяти до уваги, ти, звичайно, маєш рацію
Сем Холдер,

@SamHolder Так - Єдина ситуація, що це могло б статися, була б, якби хтось замінив базовий тип і якось зіпсував реалізацію. Це було б дивно, точно.
Дейв Біш,

4

Для того, щоб перевірити, чи об'єкт сумісний із даною змінною типу, замість того, щоб писати

u is t

вам слід писати

typeof(t).IsInstanceOfType(u)

1
Яка користь від більш детального синтаксису від синтаксису 'u is t'?
Kyle Humfeld

@KyleHumfeld Якщо у вас був Type foo; Об’єкт А; ви не можете написати "A is foo", але ви можете написати foo.isInstanceOfType (A)
Тимур Нуріясов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.