<?xml version="1.0"?>
<clause number="14.9.9" title="The is operator">
  <paragraph>The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. The result of the operation e is T, where e is an expression and T is a type, is a boolean value indicating whether e can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. The operation is evaluated as follows: <list><list_item> If the compile-time type of e is the same as T, or if an implicit reference conversion (<hyperlink>13.1.4</hyperlink>) or boxing conversion (<hyperlink>13.1.5</hyperlink>) exists from the compile-time type of e to T: </list_item><list><list_item> If e is of a reference type, the result of the operation is equivalent to evaluating e != null. </list_item><list_item> If e is of a value type, the result of the operation is true. </list_item></list><list_item> Otherwise, if an explicit reference conversion (<hyperlink>13.2.3</hyperlink>) or unboxing conversion (<hyperlink>13.2.4</hyperlink>) exists from the compile-time type of e to T, a dynamic type check is performed: </list_item><list><list_item> If the value of e is null, the result is false. </list_item><list_item> Otherwise, let R be the run-time type of the instance referenced by e. If R and T are the same type, if R is a reference type and an implicit reference conversion from R to T exists, or if R is a value type and T is an interface type that is implemented by R, the result is true. </list_item><list_item> Otherwise, the result is false. </list_item></list><list_item> Otherwise, no reference or boxing conversion of e to type T is possible, and the result of the operation is false. </list_item></list></paragraph>
  <paragraph>Note that the is operator only considers reference conversions, boxing conversions, and unboxing conversions. Other conversions, such as user defined conversions, are not considered by the is operator. </paragraph>
</clause>
