c# как оператор используется для преобразования между совместимой ссылкой или nullable типами. Это подобно операции броска, за исключением того, что это установит результат в NULL преобразования для неудавшегося преобразования, вместо того, чтобы выдать исключение.

Следующее является выборкой от официальной спецификации C# 4.0:

7.10.11 Как оператор, поскольку оператор используется для явного преобразования значения в данный ссылочный тип или nullable тип. В отличие от выражения приведения типа (§7.7.6), поскольку оператор никогда не выдает исключение. Вместо этого если обозначенное преобразование не возможно, получающееся значение является нулевым.

В операции формы E как T, E должен быть выражением, и T должен быть ссылочным типом, параметр типа, который, как известно, был ссылочным типом или nullable типом. Кроме того, по крайней мере одно из следующего должно быть верным, или иначе ошибка времени компиляции происходит:

  • Идентификационные данные (§6.1.1), неявный nullable (§6.1.4), неявная ссылка (§6.1.6), упаковывая (§6.1.7), явный nullable (§6.2.3), прямая ссылка (§6.2.4), или распаковывая (§6.2.5) преобразование существуют от E до T.

  • Тип E или T является открытым типом.

  • E является пустым литералом.

Если тип времени компиляции E не является динамичным, операция E, поскольку T приводит к тому же результату как

E is T ? (T)(E) : (T)null 

за исключением того, что E только оценен однажды. Компилятор, как могут ожидать, оптимизирует E как T для выполнения самое большее одной динамической проверки типа в противоположность двум динамическим проверкам типа, подразумеваемым расширением выше.

Если тип времени компиляции E является динамичным, в отличие от оператора броска, поскольку оператор динамично не связывается (§7.2.2). Поэтому расширение в этом случае:

E is T ? (T)(object)(E) : (T)null 

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

В примере

class X { public string F(object o) { return o as string; // OK, string is a reference type } public T G<T>(object o) where T: Attribute { return o as T; // Ok, T has a class constraint } public U H<U>(object o) { return o as U; // Error, U is unconstrained } } 

параметр типа T G, как известно, является ссылочным типом, потому что он имеет ограничение класса. Параметр типа U H не однако; следовательно использование как оператор в H запрещено.