S2219 — Runtime type checking should be simplified

Language
C#
Type
Code smell
Severity
Minor
Tags
clumsy

Why is this an issue?

To check the type of an object there are several options:

If runtime calculated Types need to be compared:

Depending on whether the type is returned by a GetType() or typeof() call, the IsAssignableFrom() and IsInstanceOfType() might be simplified. Similarly, if the type is sealed, the type comparison with == can be converted to an is call. Simplifying the calls also make null checking unnecessary because both is and IsInstanceOfType performs it already.

Finally, utilizing the most concise language constructs for type checking makes the code more readable, so

Noncompliant code example


class Fruit { }
sealed class Apple : Fruit { }

class Program
{
  static void Main()
  {
    var apple = new Apple();
    var b = apple != null && apple.GetType() == typeof (Apple); // Noncompliant
    b = typeof(Apple).IsInstanceOfType(apple); // Noncompliant
    if (apple != null)
    {
      b = typeof(Apple).IsAssignableFrom(apple.GetType()); // Noncompliant
    }
    var appleType = typeof (Apple);
    if (apple != null)
    {
      b = appleType.IsAssignableFrom(apple.GetType()); // Noncompliant
    }

    Fruit f = apple;
    if (f as Apple != null) // Noncompliant
    {
    }
    if (apple is Apple) // Noncompliant
    {
    }
  }
}

Compliant solution


class Fruit { }
sealed class Apple : Fruit { }

class Program
{
  static void Main()
  {
    var apple = new Apple();
    var b = apple is Apple;
    b = apple is Apple;
    b = apple is Apple;
    var appleType = typeof(Apple);
    b = appleType.IsInstanceOfType(apple);

    Fruit f = apple;
    if (f is Apple)
    {
    }
    if (apple != null)
    {
    }
  }
}

Exceptions

Calling GetType on an object of Nullable<T> type returns the underlying generic type parameter T, thus a comparison with typeof(Nullable<T>) can’t be simplified to use the is operator, which doesn’t make difference between T and T?.


int? i = 42;
bool condition = i.GetType() == typeof(int?); // false;
condition = i is int?; // true

No issue is reported on the following expressions:

↑ Back to top