Я заметил, что Resharper предлагает мне включить это:
if (myObj.myProp is MyType)
{
...
}
в это:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
Почему было предложено это изменение? Я привык, что Resharper предлагает изменения оптимизации и изменения кода, но мне кажется, что он хочет взять мой единственный оператор и превратить его в двухстрочный.
Согласно MSDN :
Это выражение будет истинным , если оба из следующих условий:
выражение не равно нулю. выражение можно привести к типу . То есть выражение формы
(type)(expression)
при приведении завершится без исключения исключения.
Я неправильно это понимаю или не is
выполняю те же самые проверки, просто в одной строке без необходимости явно создавать другую локальную переменную для проверки на null?
MyProp
после этого изменения вам не понадобится геттер.Ответы:
Потому что актерский состав только один. Сравните это:
к этому:
C # 7.0 поддерживает более компактный синтаксис с использованием сопоставления с образцом :
источник
as
может быть на пару наносекунд быстрее, но я считаю это преждевременной микрооптимизацией.myObj
илиmyProp
могло быть изменено (другим потоком) между приведениемis
и приведением, вызывая нежелательное поведение.as
+!= null
также будет выполнять переопределенный!=
операторMyType
if defined (даже если онmyObjRef
равен нулю). Хотя в большинстве случаев это не проблема (особенно если вы правильно ее реализуете), в некоторых крайних случаях (плохой код, производительность) это может быть нежелательно. ( хотя это должно было бы быть довольно экстремальным )object.ReferenceEquals(null, myObjRef)
.Лучший вариант - использовать сопоставление с образцом следующим образом:
источник
Пока нет информации о том, что на самом деле происходит ниже пояса. Взгляните на этот пример:
Это переводится в следующий IL:
Здесь важны звонки
isinst
иcastclass
звонки - оба относительно дороги. Если вы сравните это с альтернативой, вы увидите, что это толькоisinst
проверка:Также стоит упомянуть, что тип значения будет использовать,
unbox.any
а неcastclass
:Однако обратите внимание, что это не обязательно приводит к более быстрому результату, как мы видим здесь . Там , кажется, были улучшения , так как этот вопрос был задан вопрос , хотя: слепки , кажется , должны быть выполнены так же быстро , как они раньше, но
as
иlinq
в настоящее время примерно в 3 раза быстрее.источник
Предупреждение Resharper:
"Type check and direct cast can be replaced with try cast and check for null"
Оба будут работать, это зависит от того, насколько ваш код вам больше подходит. В моем случае я просто игнорирую это предупреждение:
В моем коде второй способ длиннее и хуже.
источник
IRunable
. Если у вас нет контроля, возможно, вы могли бы использоватьdynamic
?Мне кажется, это зависит от того, каковы шансы того, что это будет такого типа или нет. Безусловно, было бы более эффективно выполнить заброс вперед, если бы объект большую часть времени был этого типа. Если это случается только изредка, то может быть более оптимальным сначала проверить его.
Стоимость создания локальной переменной очень мала по сравнению со стоимостью проверки типа.
Читаемость и масштаб обычно являются для меня более важными факторами. Я бы не согласился с ReSharper и использовал оператор is только по этой причине; оптимизируйте позже, если это действительно узкое место.
(Я предполагаю, что вы используете
myObj.myProp is MyType
в этой функции только один раз)источник
Также должно быть предложено второе изменение:
в
Это сохраняет доступ к свойствам и приведение типов по сравнению с исходным кодом. Но это возможно только после перехода
is
наas
.источник
(MyType)
вызовет исключение, если приведение не удастся.as
только возвращаетсяnull
.is
(этот код находится в вопросе).Я бы сказал, что это делается для создания строго типизированной версии myObj.myProp, то есть myObjRef. Затем это следует использовать, когда вы ссылаетесь на это значение в блоке, вместо того, чтобы выполнять приведение.
Например, это:
лучше, чем это:
источник