Проверьте, имеет ли экземпляр тип


181

Используя это, чтобы проверить, cявляется ли экземпляр TForm.

c.GetType().Name.CompareTo("TForm") == 0

Есть ли более безопасный для типов способ сделать это помимо использования stringв качестве параметра CompareTo()?


20
Я, конечно, надеюсь, что вы не будете делать это и на Java. Java instanceofи C # is- намного лучшие способы сделать это.
Powerlord

Ответы:


410

Разные ответы здесь имеют два разных значения.

Если вы хотите проверить, является ли экземпляр точного типа, то

if (c.GetType() == typeof(TForm))

это путь

Если вы хотите знать, cявляется ли это экземпляр TForm или подкласс, используйте is/ as:

if (c is TForm)

или

TForm form = c as TForm;
if (form != null)

Стоит уяснить, какое из этих действий вы на самом деле хотите.


7
Небольшое примечание: используйте «is», если вы не хотите использовать результат приведения, и используйте «as», если вы это делаете.
Авирам Файербергер

14
С C # 7 вы можете комбинировать isи asс сопоставлением с образцом:if (x is TForm tf) {…
Ричард

39
if(c is TFrom)
{
   // Do Stuff
}

или, если вы планируете использовать cкак TForm, используйте следующий пример:

var tForm = c as TForm;
if(tForm != null)
{
   // c is of type TForm
}

Во втором примере нужно только один раз проверить, имеет ли cон тип TForm. Если вы проверяете, имеет ли cтип, а TFormзатем разыгрывают его, CLR подвергается дополнительной проверке. Вот ссылка .

Изменить: украденный у Джона Скита

Если вы хотите убедиться, что класс cесть, TFormа не какой-либо класс, наследующий его TForm, используйте

if(c.GetType() == typeof(TForm))
{
   // Do stuff cause c is of type TForm and nothing else
}

14

Да, ключевое слово "is":

if (c is TForm)
{
    ...
}

Подробности смотрите в MSDN: http://msdn.microsoft.com/en-us/library/scekt9xw(VS.80).aspx

Проверяет, совместим ли объект с данным типом. Например, это может быть определено, совместим ли объект с строковым типом как это:


10

Также несколько в том же духе

Type.IsAssignableFrom(Type c)

"Истинно, если c и текущий тип представляют один и тот же тип, или если текущий тип находится в иерархии наследования c, или если текущий тип является интерфейсом, который реализует c, или если c является параметром универсального типа и текущим типом представляет собой одно из ограничений c. "

Отсюда: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx


это также мой личный фаворит. typeof(Class).IsAssignableFrom(object.getType())похож на instanceofоператор Java .
SkidRunner

Дает ли оно ложь, если они не находятся в одной ветви иерархии наследования, но существует оператор преобразования?
Пол Стелиан

Хороший вопрос @PaulStelian. Я не уверен, что у меня в голове, но я думаю, что в этой ситуации он вернет ложь. По крайней мере, это будет моим ожидаемым поведением. Возможно, если существует неявное преобразование, оно может вернуть true, но это было бы странно.
Брэд Каннингем

Кто-нибудь, у кого установлена ​​Visual Studio, чтобы попробовать это?
Пол Стелиан

1
@PaulStelian - возвращает false. Это можно увидеть, перейдя по ссылке doc и наблюдая, что там нет упоминаний о конверсиях. Другой способ думать об этом - T1.IsAssignableFrom(T2)возвращать trueв ситуациях, когда asоператор возвращает ненулевое значение, учитывая экземпляры этих типов.
ToolmakerSteve

9

Немного более компактный, чем другие ответы, если вы хотите использовать c в качестве TForm:

if(c is TForm form){
    form.DoStuff();
}


2

Как уже упоминалось, ключевое слово «есть». Однако, если вы собираетесь позже привести его к этому типу, например.

TForm t = (TForm)c;

Тогда вы должны использовать ключевое слово «как».

например TForm t = c as TForm.

Тогда вы можете проверить

if(t != null)
{
 // put TForm specific stuff here
}

Не объединяйте, как с, потому что это дубликат проверки.



-1
bool isValid = c.GetType() == typeof(TForm) ? true : false;

или проще

bool isValid = c.GetType() == typeof(TForm);

ИМХО: я бы избегал прямого сострадания (т.е. ==). В объектных или ориентированных языках, поддерживающих наследование, если вы не знаете, что ваш конкретный тип никогда не будет наследоваться, например, от sealedкласса. Также: меня беспокоит использование троичного оператора, возвращающего (статические / постоянные) логические значения, я был бы менее обеспокоен, если бы это было switchутверждение.
SkidRunner
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.