Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redundant generic constraint?

Consider the following generic method:

public T2 Frob<T1, T2>(T1 item)
        where T1 : class, T2
        => item as T2;

The compiler will refuse to compile this code; The type parameter 'T2' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint

Ok, this is easily solvable simply doing:

public T2 Frob<T1, T2>(T1 item)
        where T1 : class, T2
        where T2 : class
        => item as T2;

But isn't this redundant? Is there any possible T2 that is not a class considering the constraints already in place for T1?

My question is not why this "inference" wasn't implemented in the compiler, the reason could simply be "no one thought about it" and thats OK. I'm more interested in knowing if my reasoning is correct in that T2 is effectively and in all cases constrained to class in the first example even if its not explicitly enforced.

like image 573
InBetween Avatar asked Feb 13 '17 16:02

InBetween


1 Answers

My interpretation of this, given the C# 5.0 specs say at 7.10.11, The as operator:

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.

The compiler at that point only considers T2 in this block:

public T2 Frob<T1, T2>(T1 item)
        where T1 : class, T2
        => item as T2;

And it sees that T2 itself is not constrained. Sure, it could deduct that in this case T1 is expected to be a reference type and inherit T2, therefore that T2 itself should also be a reference type, but I'm sure there are reasons for not doing that.

like image 182
CodeCaster Avatar answered Oct 09 '22 16:10

CodeCaster