Я видел много людей, использующих следующий код:
Type t = typeof(obj1);
if (t == typeof(int))
// Some code here
Но я знаю, что вы также можете сделать это:
if (obj1.GetType() == typeof(int))
// Some code here
Или это:
if (obj1 is int)
// Some code here
Лично я чувствую, что последний самый чистый, но есть ли что-то, что я пропускаю? Какой из них лучше использовать, или это личное предпочтение?
as
!as
хотя на самом деле это не проверка типов ...as
это, безусловно, форма проверки типов, каждаяis
такая же, как есть! Он эффективно используетсяis
за кулисами и повсеместно используется в MSDN там, где он улучшает чистоту кода по сравнению с нимis
. Вместо того, чтобы проверятьis
сначала, вызовas
устанавливает типизированную переменную, которая готова к использованию: если она пуста, ответьте соответственно; в противном случае продолжайте. Конечно то, что я видел и использовал совсем немного.as
/is
(описана в stackoverflow.com/a/27813381/477420 ), если предположить, что его семантические работы подходят для вашего случая.GetType
Метод вы ссылаетесь вSystem.Reflection.Assembly
- совершенно другим способом и не имеет значения здесь.Ответы:
Все разные.
typeof
принимает имя типа (которое вы указываете во время компиляции).GetType
получает тип времени выполнения экземпляра.is
возвращает true, если экземпляр находится в дереве наследования.пример
Да. T всегда является типом выражения. Помните, универсальный метод - это в основном целая куча методов с соответствующим типом. Пример:
источник
new Dog().GetType() is Animal
возвращает false (и вашу другую версию), поскольку.GetType()
возвращает объект типаType
, аType
не являетсяAnimal
.использование
typeof
когда вы хотите получить тип во время компиляции . Используйте,GetType
когда вы хотите получить тип во время выполнения . Редко какие-либо случаи можно использовать,is
поскольку он выполняет приведение, и, в большинстве случаев, вы в любом случае заканчиваете приведение переменной.Существует четвертый вариант, который вы не рассмотрели (особенно, если вы собираетесь привести объект к тому типу, который вы нашли); это использовать
as
.Это только использует одно приведение,
тогда как этот подход:требует два .Обновление (январь 2020 г.):
Пример:
источник
is
еще выполняет приведение?typeof()
, и этот ответ не предполагает, что вы можете. Вместо этого вы передаете тип, т. Е.typeof(string)
Работает,typeof("foo")
а не.is
выполняет актерский состав как таковую, скорее специальную операцию в IL.if (obj is Foo foo) { /* use foo here */ }
1.
Это незаконно, потому что
typeof
работает только с типами, а не с переменными. Я предполагаю, что obj1 является переменной. Таким образом, этот способtypeof
статичен и выполняет свою работу во время компиляции, а не во время выполнения.2.
Это
true
еслиobj1
точно типаint
. Еслиobj1
происходит отint
, условие if будетfalse
.3.
Это,
true
еслиobj1
isint
, или если оно происходит от вызываемого классаint
, или если он реализует вызываемый интерфейсint
.источник
Это ошибка Оператор typeof в C # может принимать только имена типов, но не объекты.
Это будет работать, но, возможно, не так, как вы ожидаете. Для типов значений, как вы показали здесь, это приемлемо, но для ссылочных типов он будет возвращать true, только если тип был точно такого же типа, а не что-то еще в иерархии наследования. Например:
Это напечатало бы
"o is something else"
, потому что типo
-Dog
нетAnimal
. Вы можете сделать эту работу, однако, если вы используетеIsAssignableFrom
методType
класса.Этот метод все еще оставляет большую проблему, хотя. Если ваша переменная равна нулю, вызов вызывает
GetType()
исключение NullReferenceException. Чтобы заставить его работать правильно, вы должны сделать:При этом вы получаете эквивалентное поведение
is
ключевого слова. Следовательно, если вы хотите именно такое поведение, вам следует использоватьis
ключевое слово, которое более читабельно и более эффективно.В большинстве случаев, однако,
is
ключевое слово все еще не то, что вы действительно хотите, потому что обычно недостаточно просто знать, что объект имеет определенный тип. Обычно вы хотите использовать этот объект как экземпляр этого типа, что также требует его приведения. И поэтому вы можете написать код вроде этого:Но это заставляет CLR проверять тип объекта до двух раз. Он проверит его один раз, чтобы удовлетворить
is
оператора, и, еслиo
это действительно такAnimal
, мы сделаем это снова, чтобы проверить приведение.Лучше сделать это вместо этого:
as
Оператор слепок , который не будет бросать исключение , если это не удается, вместо возвращенияnull
. Таким образом, CLR проверяет тип объекта только один раз, и после этого нам просто нужно выполнить нулевую проверку, что более эффективно.Но будьте осторожны: многие люди попадают в ловушку
as
. Поскольку он не генерирует исключения, некоторые люди думают о нем как о «безопасном» касте, и они используют его исключительно, избегая регулярных кастований. Это приводит к таким ошибкам:В этом случае разработчик явно предполагает, что
o
это всегда будетAnimal
, и пока их предположение верно, все работает отлично. Но если они не правы, то то, что они в конечном итоге здесь, этоNullReferenceException
. С обычным броском они получили быInvalidCastException
вместо этого, который более правильно определил бы проблему.Иногда эту ошибку бывает трудно найти:
Это еще один случай, когда разработчик явно ожидает,
o
что это будетAnimal
каждый раз, но это не очевидно в конструкторе, где используетсяas
приведение. Это не очевидно, пока вы не дойдете доInteract
метода, гдеanimal
ожидается , что поле будет назначено положительно. В этом случае вы не только получите ложное исключение, но оно не будет выдано до тех пор, пока потенциально не произойдет намного позже, чем произошла фактическая ошибка.В итоге:
Если вам нужно только знать, относится ли объект к какому-либо типу, используйте
is
.Если вам нужно обработать объект как экземпляр определенного типа, но вы точно не знаете, что объект будет этого типа, используйте
as
и проверьтеnull
.Если вам нужно обработать объект как экземпляр определенного типа, и объект должен быть этого типа, используйте обычное приведение.
источник
o is Animal
, что требует CLR , чтобы проверить , если тип переменнойo
являетсяAnimal
. Второй раз, когда он проверяет, это когда он бросает в заявлении((Animal)o).Speak()
. Вместо того, чтобы проверить дважды, проверьте один раз, используяas
.Если вы используете C # 7, то пришло время обновить великолепный ответ Эндрю Хэра. Сопоставление с образцом ввело хороший ярлык, который дает нам типизированную переменную в контексте оператора if, не требуя отдельного объявления / приведения и проверки:
Это выглядит довольно обескураживающе для такого броска, но на самом деле светит, когда в вашу программу входит много возможных типов. Ниже приведен старый способ избежать сотворения дважды:
Работа над тем, чтобы максимально сократить этот код, а также избежать дублирования приведения к одному и тому же объекту, всегда беспокоила меня. Вышесказанное красиво сжато с шаблоном, соответствующим следующему:
РЕДАКТИРОВАТЬ: Обновлен более длинный новый метод, чтобы использовать переключатель в соответствии с комментарием Палека.
источник
switch
оператор с сопоставлением с образцом .if (obj1 is int integerValue) { integerValue++; }
Я имел
Type
-property для сравнения и не мог использоватьis
(какmy_type is _BaseTypetoLookFor
), но я мог использовать это:Обратите внимание на это
IsInstanceOfType
иIsAssignableFrom
возвращаетtrue
при сравнении тех же типов, где IsSubClassOf будет возвращатьfalse
. ИIsSubclassOf
не работает на интерфейсах, где другие два делают. (Смотрите также этот вопрос и ответ .)источник
Я предпочитаю это
Тем не менее, если вы используете is , вы, вероятно, не используете наследование должным образом.
Предположим, что Персона: Сущность, а это Животное: Сущность. Feed - это виртуальный метод в Entity (чтобы сделать Нила счастливым)
Скорее
источник
Я считаю, что последний также рассматривает наследование (например, Dog is Animal == true), что в большинстве случаев лучше.
источник
Это зависит от того, что я делаю. Если мне нужно значение bool (скажем, чтобы определить, буду ли я приводить к int), я буду использовать
is
. Если я действительно нуждаюсь в типе по какой-то причине (скажем, чтобы перейти к другому методу), я буду использоватьGetType()
.источник
Последний чище, более очевиден, а также проверяет подтипы. Другие не проверяют на полиморфизм.
источник
Используется для получения объекта System.Type для типа. Выражение typeof принимает следующую форму:
В этом примере используется метод GetType для определения типа, который используется для хранения результата числового вычисления. Это зависит от требований к хранению полученного числа.
источник
источник
Вы можете использовать оператор "typeof ()" в C #, но вам нужно вызвать пространство имен с помощью System.IO; Вы должны использовать ключевое слово "is", если хотите проверить тип.
источник
typeof
не определен в пространстве имен, это ключевое слово.System.IO
не имеет к этому никакого отношения.Тест производительности typeof () против GetType ():
Результаты в режиме отладки:
Результаты в режиме релиза:
источник
DateTime
не следует использовать, если вы беспокоитесь о временах ниже 100 мс , так как он использует временные рамки ОС. По сравнению с темStopwatch
, в котором используются процессорыTick
, разрешение, используемоеDateTime
в Win7, составляет колоссальные 15 мс.