Difference between is and .GetType() == typeof(class)

  • Thread starter Thread starter iCeCLoW
  • Start date Start date
I

iCeCLoW

What is the difference between doing this:

if (myClass is Class)
{
//Do something here
}

and this?:

if (myClass.GetType() == typeof(Class))
{
//Do something here
}

Because in some cases the first expression evaluates to false but the
second expression remains true. When this happens I can always cast
myClass to the type Class.

What I´m missing here?

Thanks in advance
 
Hi,
It's not exactly the same, and the problem appears when you use
inheritance.
ie: WebPage1 inherits from Page, and this one inherits also from
Object, so if you test for (new WebPage1()).GetType() ==
typeof(object) it'll return false because the types are diferent, but
when you test using the IS operator it's true.
((new WebPage1()) is object) is true because (new WebPage1()) is an
object of type WebPage1, and algo a Page and an object.
The types might be different, but IS checks if you can cast safely to
this type.

Bye,
Diego
 
iCeCLoW said:
What is the difference between doing this:

if (myClass is Class)
{
//Do something here
}

and this?:

if (myClass.GetType() == typeof(Class))
{
//Do something here
}

Because in some cases the first expression evaluates to false but the
second expression remains true.

Could you post a short but complete program which demonstrates this?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

I can see how the opposite would happen, just by virtue of derived
classes where myClass refers to an instance of a class derived from
Class - but I can't see why the first would be false and the second
true.
 
I can see how the opposite would happen, just by virtue of derived
classes where myClass refers to an instance of a class derived from
Class - but I can't see why the first would be false and the second
true.

Ooh - I've worked out a nasty bit of code where it would be the way
round you said. It's dirty though:

using System;

class EvilType
{
public new Type GetType()
{
return typeof(InnocentType);
}
}

class InnocentType
{
}

class Test
{
static void Main()
{
EvilType evil = new EvilType();
Console.WriteLine ("evil is InnocentType? {0}",
evil is InnocentType);
Console.WriteLine ("evil.GetType()==typeof(InnocentType)? {0}",
evil.GetType()==typeof(InnocentType));
}
}

The cast would also succeed if you had an explicit conversion from
EvilType to InnocentType.

I feel like I ought to have a bath after writing that...
 
Because in some cases the first expression evaluates to false but the
second expression remains true. When this happens I can always cast
myClass to the type Class.

Diego is correct. The "is" operator tests for type _compatibility_
(basically Liskov substitutability [1]) whereas the comparison GetType
== typeof tests for type _identity_.

Type A is identical with type B only if both are the exact same type.

But A is compatible with B if A is the same type or a derived type.
That includes interface implementations, e.g. if you declare class A:
IDisposable then the test (A is IDisposable) will succeed.

[1] http://en.wikipedia.org/wiki/Liskov_substitution_principle
 
I can see how the opposite would happen, just by virtue of derived
classes where myClass refers to an instance of a class derived from
Class - but I can't see why the first would be false and the second
true.

Well spotted, I missed that when I first read the original post. I'm
pretty sure it's just a typo, though, and he did mean to say the
opposite. Without horrible contortions as in your example, the "is"
comparison always succeeds where the GetType comparison does.
 
Back
Top