'TypeCode vs typeof

If I need some type-specific code, I could use typeof for example:

private static bool IsNumericType(Type type)
{
    return type == typeof(int) || type == typeof(decimal); //etc
}

But I could also use the enum TypeCode

private static bool IsNumeric(TypeCode objTypeCode)
{
    return objTypeCode == TypeCode.Int16 || objTypeCode == TypeCode.Int32 || objTypeCode == TypeCode.Int64; // etc ||
}

What is the benefit of using TypeCode over typeof from an architectural and performance viewpoint? In which case should I use the one of the two?

FYI, the code to get the type / typeCode from an value:

var type = value.GetType();
var typeCode =  Convert.GetTypeCode(value);

PS: These examples are strongly simplified.

PS 2: If I pass the value, I could also use as, is etc. But In this case I don't like to send as the method doesn't need to know the value, only it's type.



Solution 1:[1]

TypeCode works best when you are following several possible paths, and most or all of the logic can be done by examining the code alone as then switching on that will be pretty efficient, and generally pretty clear.

In other cases you are likely to have as much logic inside the Object branch as outside since that is the code for most types, in which case it tends not to be as useful to examine the code first unless perhaps the cases that are served well by it are also cases that come up particularly often.

Your IsNumeric example is a good example of when TypeCode works well as if you rewrite it to a switch you are answering with one virtual call to get the code and one switch of the sort that compiles to relatively efficient jumps rather than branch on multiple comparisons of different possible types.

Note that enum types have the same code as their underlying numeric types. Whether that counts as having those cases covered for free, or as a case you'll have to guard against separately depends on how you want to consider those types for whatever your purpose is.

Solution 2:[2]

A few notes before I answer:

  1. typeof takes a type (NOT an instance)
  2. IConvertible.GetTypeCode requires an instance that implements the IConvertible interface

Thus they are different. So the question you need to ask yourself is do you want the type of an instance or a type.


This is from Microsoft Docs:

Call the GetTypeCode method on classes that implement the IConvertible interface to obtain the type code for an instance of that class.
Otherwise, call an object's GetType method to obtain its Type object, then call the Type object's GetTypeCode method to obtain the object's type code.

Therefore, if a type does not implement IConvertible interface, then you need to make 2 calls: GetType and then call GetTypeCode. I also pulled the code from .NET source code for GetTypeCode:

    public static TypeCode GetTypeCode(Type type)
    {
        if (type == null)
            return TypeCode.Empty;
        return type.GetTypeCodeImpl();
    }
    
    protected virtual TypeCode GetTypeCodeImpl()
    {
        // System.RuntimeType overrides GetTypeCodeInternal
        // so we can assume that this is not a runtime type
    
        // this is true for EnumBuilder but not the other System.Type subclasses in BCL
        if (this != UnderlyingSystemType && UnderlyingSystemType != null)
            return Type.GetTypeCode(UnderlyingSystemType);
        
        return TypeCode.Object;
    }

As you can see there is quite a bit going on there. Now without bench-marking it is hard to say but I am pretty sure since typeof is compile time, and it is native to C#, the team has put work into it to make it efficient. The fact that typeof is:

  1. Native to C#
  2. Decided at compile time
  3. Does not depend on an interface
  4. Is not 2 calls in some cases
  5. It is more straight forward

I would go with typeof.

I always remember this rule:

First make it work. Then, only if you need to make it work faster, change it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Dai