Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check type of an object in a switch/case?

Tags:

dart

I see in examples this code:

if (obj is User) { // do something }

I want to check the type of the object in a switch/case flow, and found a property .runtimeType of the object:

switch (obj.runtimeType) {
    case User:
        print(obj);
        break;
}

Is this a correct way to check the type of the object?

like image 649
Sergei Basharov Avatar asked Mar 15 '17 06:03

Sergei Basharov


People also ask

How can you tell what type of object something is?

Check if Object is of type Map in JavaScript # Use the instanceof operator to check if an object is a Set - myObj instanceof Set . The instanceof operator returns true if the prototype property of a constructor appears in the prototype chain of the object.

Is Typeof C#?

The C# typeof operator ( GetType operator in Visual Basic) is used to get a Type object representing String. From this Type object, the GetMethod method is used to get a MethodInfo representing the String.


1 Answers

There is no support in the Dart switch statement for switching by type. You should use a sequence of if tests instead:

if (obj is User) { 
  print(obj);
} else if (obj is ...) ...

I really, really recommend that you never use runtimeType for anything.

It can be used to reflect, using dart:mirrors, on the type of an object (but you can also just use reflect(object) to reflect on the object itself). Apart from that, using runtimeType almost always causes otherwise avoidable problems.

The only thing you can do with the Type object returned by runtimeType is to check it for equality. If you do that (like in the switch above), then you don't correctly handle subtypes. If you ever have a subtype of User in your system, like if User is an interface and the implementation class is different, or if you mock a User for testing, or any number of other causes, then the instance will not have User as runtimeType, and the code won't recognize it. Or maybe it will, because runtimeType can be overridden by the user, and any class can choose to return User. Testing against runtimeType isn't a guarantee that the class is actually the one you check for.

When you compare for type, you should always use is because it correctly handles subclasses. Subtype substitutability is one of the core ideas of object oriented programming, so you could say that if you use runtimeType, you are probably not doing an optimal OO design.

(There are cases where code uses other.runtimeType == MyClass in operator== to avoid being equal to a subclass instance to avoid the "ColorPoint" problem - but it means that it's impossible to make a subclass or interface implementation (which includes mocks) of that type and have it pass equality checks. That's a very subtle restriction that I would avoid in shared library code. What you do in your own application, that nobody else will depend on, is at least only your problem :smile:).

like image 168
lrn Avatar answered Sep 22 '22 09:09

lrn