-4

What's the quickest way to check an object's type in C#?

There seems to many ways to do it; as, is, GetType(), typeof, and I want the fastest. The objects I have are simple, and there is no inheritance to worry about.

Here's pseudo code of how it needs to work:

if (x == ClassY) 
{
    doYStuff();
    return
}

if (x == ClassZ) 
{
    doZStuff();
    return
}

Repeat a lot with other Class types...

Suggestions welcome, and hope you're all good.

Thanks.

TinyRacoon
  • 4,655
  • 2
  • 23
  • 22
  • 4
    My suggestions are to (1) write a benchmark and (2) go to the google.-- As an aside, the code smells. Such choices should typically be made by polymorphism (through different interface implementations). – Peter - Reinstate Monica Mar 20 '20 at 11:17
  • Thanks Peter. All good suggestions. My Google search sadly wasn't definitive. And I guessed others would know the answer, so writing my own bench mark tests seemed a bit silly. I agree about the smell, it doesn't look pretty. But it's what I have to work with. Ta. – TinyRacoon Mar 20 '20 at 11:22
  • So you cannot alter the class hierarchy? I mean, change the definition of ClassX and ClassY? And btw, even if not: Create a separate interface with a doStuff() method and provide your own implementing classes which *contain* (or maybe inherit) from ClassX,Y,Z, call `doX,Y,ZStuff()` in their implementation of `doStuff` and then pass around `x`s which have the type of the interface, and simply call `doStuff()` without any if or switch. – Peter - Reinstate Monica Mar 20 '20 at 11:23
  • 1
    Note that there quite a lot of old posts asking the very same question, e.g. [Fastest Type Comparison?](https://stackoverflow.com/questions/378643/fastest-type-comparison/378657) or [What is the fastest way to check a type?](https://stackoverflow.com/questions/17774255/what-is-the-fastest-way-to-check-a-type). However, I could not find one that does thorough benchmarks for all possible approaches. If I did not miss one and this post gets a complete answer, someone with sufficient privileges should consider closing some of those duplicates. – janw Mar 20 '20 at 11:39
  • Does this answer your question? [Which is good to use: Object.GetType() == typeof(Type) or Object is Type?](https://stackoverflow.com/questions/27813304/which-is-good-to-use-object-gettype-typeoftype-or-object-is-type) – janw Mar 20 '20 at 11:44
  • ...found one. This does not measure `as`, but `as` is actually doing `is` behind the scenes. There are also measurments for `is` vs. `enum`-based approaches: [C# 'is' operator performance](https://stackoverflow.com/questions/686412/c-sharp-is-operator-performance). This one again is marked as a duplicate of [this question](https://stackoverflow.com/questions/983030/type-checking-typeof-gettype-or-is). – janw Mar 20 '20 at 11:45

2 Answers2

1

If you're worried about performance then checking for types is never a great idea. You should looks to see if you can write your code so that they derivce from a common base that has a doStuff method and then have the derived classes override the method. For example:

abstract class Base
{
    public abstract void DoStuff();
}

class ClassX : Base
{
    public override void DoStuff()
    {
        Console.WriteLine("ClassX DoStuff");
    }
}

class ClassY : Base
{
    public override void DoStuff()
    {
        Console.WriteLine("ClassY DoStuff");
    }
}

Now you can just say:

x.DoStuff();

And not have to worry about checking types. This also means you won't have to keep changing your if statement every time a new type comes along that you need to handle.

However, if you are planning to check the types then a neat and tidy way is to use a switch statement:

switch(x)
{
    case ClassX classX:
        Console.WriteLine("ClassX");
        break;

    case ClassY classy:
        Console.WriteLine("ClassY");
        break;
}
Sean
  • 60,939
  • 11
  • 97
  • 136
0

Use the is operator, https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is

if (x is ClassY) 
{
    doYStuff();
    return
}

if (x is ClassZ) 
{
    doZStuff();
    return
}

It can also be used to check for implementations

if (x is IClassY) 
{
    doYStuff();
    return
}

if (x is IClassZ) 
{
    doZStuff();
    return
}
Eric Herlitz
  • 25,354
  • 27
  • 113
  • 157
  • But do you agree that this is typically an indicator of a design problem? In that case, include that caveat in your post, and perhaps sketch out the alternative.You know, 200 beginners are copying this right now off of stackoverflow. – Peter - Reinstate Monica Mar 20 '20 at 11:21
  • @Peter-ReinstateMonica It may but then again it may not be a design issue. I'd say if you are writing something new you should try to honour the Single Responsibility Principle but in many cases, developers are modernizing and maintaining older applications where SRP isn't an option. – Eric Herlitz Mar 20 '20 at 11:25