I’m a little foggy on System.Type versus an actual class type (like Object or XmlDocument) in .NET… will this code correctly determine if the type of a particular object is equal to a class I specify?
' Given "myObject" (unknown type), and some class type (let's say "MyClass")...
If myObject.GetType.Equals(MyClass)
If TypeOf(myObject) Is MyClass
If myObject.GetType() Is MyClass
Which one is correct?
Bonus points if you can provide some information on what a class identifier is versus what a System.Type is. 🙂
Note: The language doesn’t matter here, VB.NET or C# is fine, the code above is pseudocode.
Fist let’s take a look on the three options you gave:
This will probably result in a error, since the equals expects a
System.Type, not a class. A class definition is not aSystem.Type, but you can retrieve it using thetypeofoperator. So you could doinstance.Equals(typeof(MyClass)), which would return true if the object is of the given class.Conversely, you can’t use
typeofwith instances, only with classes, so the above code would fail. Also, theisoperator automatically checks the typing so you can’t do atypeofor aGetTypewhen using it. You should go withif myObject is MyClass, which would return true if myObject can be cast toMyClass. This is different from saying that it’s an instance of that type, because it could be that myObject is an instance of a class that inherits fromMyClass.Again, the
isoperator already checks the type on both operands, so you should go withif myObject is MyClass.All that said, I’d like to explain the “theory” behind the type system. I’m no specialist, so I’m giving you a more practical explanation:
A class definition label (like
MyClass) is not a System.Type. ASystem.Typeis a metadata class that is generated by the CLR to represent the type defined by your label. To retrieve theSystem.Typerelated to a certain class definition label, use thetypeofoperator as follows:On a object instance, you can retrieve the
System.Typemetadata by calling the methodGetType()on it. It will give you an instance ofSystem.Typerelated to the class that represents the actual instance. This means that if your object is being treated by the compiler as a interface or a base class,.GetType()still gives you the most derived type for that instance.You can compare
System.Typein order to check if two objects are instances of the same class, but again, beware that your instance can be of a more derived type; The equality will fail (theSystem.Typeof a more derived class is different than that of a less derived one).If you need to take inheritance into account, you can use the method
IsAssignableFrom, like this:C# and VB.Net gives you two operators that enables you to do type checking on the fly,
isandas.isdoes automatic typing retrieval and is preferred over getting theSystem.Typeyourself. It accounts for inheritance as well:If you need to check the type and cast the object use
as:What you cannot do with
asis not perform proper result checking; The problem is that if you don’t check it for null and use it, you get anNullReferenceException, which will hide the correct problem (the cast failed). If you are sure you can do the cast, then use a explicit cast:This will throw an
InvalidCastException, so the code will be easier to debug.