ECMA-334: 14.9.11 as operator
14.9.11 as operator
The as operator is used to explicitly convert a value to a given reference type or nullable type. When
converting to a reference type, the as operator uses a reference conversion or a boxing conversion. When
converting to a nullable type, the as operator uses a wrapping conversion, an unboxing conversion, or a null
type conversion (§13.7.1). Unlike a cast expression (§14.6.6), the as operator never throws an exception.
Instead, if the indicated conversion is not possible, the resulting value is null.
In an operation of the form e as T, e shall be an expression and T shall be a reference type, a type parameter
that is known to be a reference type (§25.7), or a nullable type. The type of the result is T, and the result is
always classified as a value. The operation is evaluated as follows:
- If the compile-time type of
eis the same asT, the result is simply the value ofe. - Otherwise, if an implicit reference conversion (§13.1.4), boxing conversion (§13.1.5), wrapping conversion (§13.7), or null type conversion (§13.7.1) exists from the compile-time type of
etoT, this conversion is performed and becomes the result of the operation. - Otherwise, if an explicit reference conversion (§13.2.3) or unboxing conversion (§13.2.4) exists from the compile-time type of
etoT, a dynamic type check is performed:- If the value of
eisnull, the result is the valuenullwith the compile-time typeT. - Otherwise, if
Tis a nullable type, letRbe the run-time type of the instance referenced bye. IfRis the underlying type ofT, then the result is equivalent to unboxing the value given byeto the typeT. - Otherwise, let
Rbe the run-time type of the instance referenced bye. IfRandTare the same type, ifRis a reference type and an implicit reference conversion fromRtoTexists, or ifRis a value type andTis an interface type that is implemented byR, the result is the reference given byewith the compile-time typeT. - Otherwise, the result is the value
nullwith the compile-time typeT.
- If the value of
- Otherwise, if the compile-time type of
eorTis an open type (§25.5.2), a dynamic type check is performed. - Otherwise, the indicated conversion is never possible, and a compile-time error occurs.
The as operator only performs reference conversions, boxing conversions, unboxing conversions, and
unwrapping conversions. Other conversions, such as user defined conversions, are not possible with the as
operator and should instead be performed using cast expressions.
The as operator can be used with a type parameter T (§25.1.1) as the right-hand side only if T is known to
be a reference type (§25.7). This restriction is required because the value null might be returned as a result
of the operator. [Example:
class X { public T F<T>(object o) where T: Attribute { return o as T; // Ok, T has a class type constraint } public T G<T>(object o) { return o as T; // Error, unconstrained T } }
end example]
[Note: When constraints are factored in, there are situations where the compiler can conclude that the
operation e as T will never succeed, for example, when e is a struct or sealed class that doesn’t implement
a particular interface, and T is constrained to require that interface. However, a complete specification of
those situations is complicated, and the rules given above seem to be the best compromise. end note]