IsAssignableFrom, IsInstanceOfType and the is keyword, what is the difference?

Solution 1:

You use whatever you have the information for.

If you have an instance and a static type you want to check against, use is.

If you don't have the static type, you just have a Type object, but you have an instance you want to check, use IsInstanceOfType.

If you don't have an instance and you just want to check the compatibility between a theoretical instance of a Type and another Type, use IsAssignableFrom.

But really is seems like you are just re-implementing the as operator (except that yours would also work for non-nullable value types, which is usually not a big limitation).

Solution 2:

I guess you're effectively implementing a version of the as operator that works with value types as well as reference types.

I'd go for:

public static T SafeCastAs<T>(this object obj)
{
    return (obj is T) ? (T) obj : default(T);
}

IsAssignableFrom works with types, and is works with instances. They will give you the same results in your case, so you should use the simplest version IMHO.

As for IsInstanceOfType:That is implemented in terms of IsAssignableFrom, so there will be no difference.

You can prove that by using Reflector to look at the definition of IsInstanceOfType():

public virtual bool IsInstanceOfType(object o)
{
    if (o == null)
    {
        return false;
    }
    return this.IsAssignableFrom(o.GetType());
}

Solution 3:

I guess you should just go with "as" instead of your custom "SafeCastAs". But this will work only for classes (not structs), so if you want to use this method for structs as well I can get it.

Operator "is" basically gives you the same as Type.IsAssignableFrom, so you can keep only "is", it checks if you can safely cast obj to T, without exceptions. So it will cover both previous checks in your method. But you should be aware about that it does not check if you can assign obj to T, because of user defined conversions: explicit and implicit keywords.