119
User u = new User();
Type t = typeof(User);

u is User -> returns true

u is t -> compilation error

How do I test if some variable is of some type in this way?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Karan
  • 14,824
  • 24
  • 91
  • 157

4 Answers4

229

The other answers all contain significant omissions.

The is operator does not check if the runtime type of the operand is exactly the given type; rather, it checks to see if the runtime type is compatible with the given type:

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

But checking for type identity with reflection checks for identity, not for compatibility

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false,
// even though x is an animal

// or with the variable "Type t" from the question:
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false,
// even though x is an animal

If that's not what you want, then you probably want IsAssignableFrom:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true,
// a variable of type Animal may be assigned a Tiger.

// or with the variable "Type t" from the question:
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 9
    While the final approach shown here works, it's needlessly verbose. `typeof(Animal).IsInstanceOfType(x)` is shorter and more straightforward than `typeof(Animal).IsAssignableFrom(x.GetType());` (and Resharper will suggest using the former if you use the latter). – Mark Amery May 26 '17 at 10:19
  • 1
    CLARIFICATION: to answer the original question, substitute `t` for `typeof(Animal)`. So Mark's improved form becomes `t.IsInstanceOfType(x)`. – ToolmakerSteve Jun 07 '18 at 02:59
16

GetType() exists on every single framework type, because it is defined on the base object type. So, regardless of the type itself, you can use it to return the underlying Type

So, all you need to do is:

u.GetType() == t
Dave Bish
  • 19,263
  • 7
  • 46
  • 63
  • 2
    Actually Eric's answer is helpful and all, but does not answer the actual question of how to test with an unknown type in the "u is t" manner described in the original question, and yours does. – Daniel Jan 22 '16 at 15:05
  • @Daniel - Not exactly. Dave's answer is only correct if you want to *exclude* subclasses of t. Eric's answer mostly explains what to do; it is just missing clarification of where to put "t". I'll add a comment there. – ToolmakerSteve Jun 07 '18 at 02:57
11

You need to see if the Type of your instance is equal to the Type of the class. To get the type of the instance you use the GetType() method:

 u.GetType().Equals(t);

or

 u.GetType.Equals(typeof(User));

should do it. Obviously you could use '==' to do your comparison if you prefer.

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • +1 But prefer the second choise. `u.GetType.Equals(typeof(User));` – Omar May 02 '12 at 14:06
  • One reason this is less safe than using == - is that if GetType() somehow returns null - it'll throw. – Dave Bish May 02 '12 at 14:07
  • 1
    @Fuex, yeah me to, I think it makes the code easier to read if the typeof is inline, which is why I posted it like that, even though in the OPs example he already has a variable `t` which contains the type. – Sam Holder May 02 '12 at 14:07
  • @DaveBish if GetType returned null, then I'd be worried that plenty of things would start to throw... but point taken, you are of course right – Sam Holder May 02 '12 at 14:11
  • @SamHolder Yeah - The only situation this would happen, would be if someone overrode a base type, and screwed up the implementation somehow. It'd be weird, for sure. – Dave Bish May 02 '12 at 14:19
5

In order to check if an object is compatible with a given type variable, instead of writing

u is t

you should write

typeof(t).IsInstanceOfType(u)