2010-09-16 2 views

ответ

18

Использование as не сможет корректно, если объект является неправильным типом, и полученное значение будет нулевым, где нормальный бросок будет бросать InvalidCastException:

object x = new object(); 
string y = x as string; // y == null 
string z = (string)x; // InvalidCastException 
1

as литья будет nerer бросить исключение, в то время как обычный литье возможно.

Object a = new Object(); 
String b = a as String; 
if(b != null) // always false for this example. 
{} 
1

Нормальный тип броска может возвращать IllegalTypeCast исключение, где, как as вернется null в этом случае.

1
((Class2) obj) // Throws exception when the casting cannot be made 

Class2 C = obj as Class2 // Will return NULL if the casting cannot be made 
0

as не может быть использован с типами значений (не обнуляемых типов).

Для ссылочных типов ...

expression as type 

действительно так же, как

expression is type ? (type) expression : (type) null 

за исключением того, expression вычисляется только один раз.

В знак уважения к Биллу Клинтону, по выражению 'is' в 'expression is type', я имею в виду 'is'.

В основном, как указывают другие ответы, это означает, что при возврате null, когда приведение произойдет неудачно. Тем не менее, он также возвращает null, когда кастинг будет успешным, но тип неправильный.

Вот несколько глупый пример:

uint? u = 52; 
int? i = (int?) u; // 'i' is now 52 

но

uint? u = 52; 
object d = u; 
int? i = d as int?; 

Что такое значение I? 52? Неа. Он равен нулю.

Зачем нужен объект? Оказывается, я солгал выше, когда объяснял «как» в терминах «есть».

Наблюдайте:

uint? u = 52; 
int? i = (u is int?) ? (int?) u : (int?) null; 

'я' теперь null

uint? u = 52; 
int? i = u as int?; 

К сожалению. Ошибка компилятора. Итак, я думаю, что два утверждения не совсем одинаковы.

+2

Вкратце: есть есть и как есть, как есть. –

+0

Не только это, но я должен написать C#, который использует '?' например, Lisp использует скобки. :-) – Justin

7

Варианты использования двух операторов поверхностно похожи, но семантически совершенно разные. Листинг сообщает читателю: «Я уверен, что это преобразование является законным, и я готов принять исключение во время выполнения, если я ошибаюсь». Оператор «как» сообщает: «Я не знаю, является ли это преобразование законным или нет, мы попробуем его и посмотрим, как это получится».

Более подробной информации по этой теме моей статьи на эту тему:

http://blogs.msdn.com/b/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

+1

Он может сообщить это, но не обязательно. Я использовал ключевое слово 'as', когда я уверен, что преобразование будет работать, потому что я просто предпочитаю смотреть на:' (myobj как MyType) .SomeProperty' over '((MyType) myobj) .SomeProperty' В этом случае путь, который я сделал, сообщает, что я готов взять «NullReferenceException» во время выполнения, если это не так. Просто хотел отметить, что это стилистическая вещь. – jasonh

+1

@ jasonh - Использование 'as' таким образом читается как стилистически неправильно для меня. Это заставило бы нас задуматься, почему актерский состав не был выполнен. Кроме того, недопустимое исключение лить может привести разработчика к проблеме быстрее, чем исключение с нулевой ссылкой. Я предпочитаю стиль Эрика. –

0

Вы никогда не получите превращающее исключение, если вы используете «в качестве» ключевого слова. Результатом конвертации будет null, если вы попробуете недействительный конвертировать.

Неявно/явно конвертировать может использоваться между классами/интерфейсами с отношениями наследования/реализации, иначе это даст ошибку компиляции. Смотрите пример:

public class A {} 
public class B {} 
... 
A a = new A(); 
//B b = (B)a; //compile error:Cannot implicitly convert type 'A' to 'B' 

другой ситуации неявно/явное преобразование существует никакой связи между класса А и В, но вы пишете implicit/explicit оператор самостоятельно.

0

Также, как можно использовать только со ссылочными типами. Это на самом деле вполне логично, поскольку если преобразование завершается неудачно, оно возвращает false, и это не является возможным значением для типа значения.

Так что для типов значений необходимо использовать обычное приведение типов.

Смежные вопросы