В чем разница между литьем и использованием "как" в С#?
Если есть разница, в чем разница между двумя способами выполнения следующего литья?
В этом случае e
является объектом GridViewRowEventArgs
.
GridView gv = (GridView)e.Row.FindControl("gv"); //first way
GridView gv2 = e.Row.FindControl("gv") as GridView; //second way
Ответы
Ответ 1
Различия заключаются в следующем:
- Если сбой не выполняется, он выдает
InvalidCastException
.
- Если оператор
as
выходит из строя, он просто возвращает нулевую ссылку.
- Вы не можете использовать
as
с типами значений, не допускающих нулевое значение (например, вы не можете сделать "o as int
" ).
- Оператор литья также используется для распаковки. (
as
можно использовать для unbox для типа значения NULL.)
- Оператор трансляции также может выполнять пользовательские преобразования.
EDIT: Я написал в другом месте о том, когда мне представляется целесообразным использовать этого оператора. Это может быть полезно прочитать...
Ответ 2
В вышеприведенных ответах не упоминается intent - почему вы выполняете преобразование и (что еще более важно), что происходит на линиях после преобразования?
Например, я несколько раз видел код, похожий на следующий:
if ((foo as SomeType).SomeMethod()) { /* ... */ }
Это можно сравнить с версией для литья:
if (((SomeType) foo).SomeMethod()) { /* ... */ }
Итак, какой из них лучше?
Листинг.
Использование as
приведет к NullReferenceException
, если преобразование завершится с ошибкой.
Использование трансляции приведет к InvalidCastException
, если преобразование завершится с ошибкой.
Теперь скажите мне, что является более полезным исключением для отладки? A NullReferenceException
, который может быть произведен почти любым, или InvalidCastException
, который позволяет вам узнать, что на самом деле пошло не так?
Таким образом, only использует as
, если преобразование фактически необязательно (это означает, что должен быть тегом null
перед использованием переменная). В противном случае используйте бросок, делая ваши намерения более явными.
Ответ 3
В общем, разница между статическим приложением и "как" заключается в том, что приведение будет вызывать исключение, если оно терпит неудачу, тогда как "как" просто установит переменную в значение null.
Ответ 4
Оператор "как" в основном делает попытку использовать переменную и возвращает null, если она терпит неудачу, а не бросает исключение. Таким образом, значение, к которому вы производите, должно быть нулевым - ссылочным или примитивным. В вашем примере вам нужно будет:
int? i2 = o as int;
или он не будет компилироваться.
Ответ 5
Безопасный листинг как
variable as type
делает то же самое, что и
(variable is type) ? (type)variable : (type)null
и не будет работать для типов значений.
Ответ 6
Если вы, однако, использовали ссылочный тип say Table, первый из них повысил бы InvalidCastException в случае, если o не был назначен для таблицы, а второй просто вернул значение null.
Ответ 7
Помимо вопроса, который указал Джон, ключевое слово as
эффективно выполняет o
как SomeClass
. Если o
не выводится из SomeClass
, он возвращает null
. Принимая во внимание, что простой бросок выдает исключение.
SomeClass i2 = o as SomeClass;
становится
SomeClass i2;
if (o is SomeClass)
i2 = (SomeClass)o;
else
i2 = null;
Ответ 8
Я мог бы заявить очевидное здесь, но одна вещь, которую вы получаете с помощью "as", заключается в том, что вы гарантированно получите объект с запрошенным типом.
Это пригодится в определенных ситуациях.