Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conflicting compile time behaviour using as keyword against generic types in C#

Tags:

c#

generics

When attempting to use the C# "as" keyword against a non-generic type that cannot be cast to, the compiler gives an error that the type cannot be converted.

However when using the "as" keyword against a generic type the compiler gives no error:

public class Foo { }

public class Bar<T> { }

public class Usage<T> {
   public void Test() {
      EventArgs args = new EventArgs();
      var foo = args as Foo;     // Compiler Error: cannot convert type
      var bar = args as Bar<T>;  // No compiler error
   }
}

I discovered this behaviour in a much larger code base where the lack of a compile time error led to an issue at runtime.

Is the conflicting behaviour by design? If so, does anyone have any insight as to why?

like image 250
Phillip Trelford Avatar asked Jan 26 '15 12:01

Phillip Trelford


1 Answers

In §7.10.11 The as operator C# 5.0 Specification says:

In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type. Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:

  • An identity (§6.1.1), implicit nullable (§6.1.4), implicit reference (§6.1.6), boxing (§6.1.7), explicit nullable (§6.2.3), explicit reference (§6.2.4), or unboxing (§6.2.5) conversion exists from E to T.

  • The type of E or T is an open type.

  • E is the null literal.

So args as Foo gives an error because none of this is true. But in the second case, Bar<T> is an open type, and the spec explains open type as, §4.4.2 Open and closed types :

An open type is a type that involves type parameters. More specifically:

  • A type parameter defines an open type. [...]
like image 183
Selman Genç Avatar answered Nov 04 '22 01:11

Selman Genç