C# 7.0 case pattern matching on generic parameter

neonxc picture neonxc · Jun 25, 2017 · Viewed 8.1k times · Source

Is there a reason for not being able to handle a generic variable by the type pattern? Please consider the code:

public static int CompareValues<T>(T left, T right)
{
  switch (left)
  {
    case IComparable<T> comparableDif:
      return comparableDif.CompareTo(right);
    case System.Numerics.Complex c:
      return c.Magnitude
        .CompareTo(((System.Numerics.Complex)(object)right).Magnitude);
    default:
      throw new ArgumentException("unsupported type");
  }
}

The first match on the IComparable interface is ok, but the second one does not compile. Why do I have to use this boxing workaround?

case object o when o is System.Numerics.Complex:
  return ((System.Numerics.Complex)o).Magnitude
    .CompareTo(((System.Numerics.Complex)(object)right).Magnitude);

Answer

svick picture svick · Jun 25, 2017

This is a consequence of how pattern matching in C# 7.0 is defined: for your type pattern to compile, a cast from T to Complex would have to exist, but it does not. The C# team realized it was a mistake to require this, so this issue was fixed in C# 7.1.