Writing a generic casting extension-method
This design looks to me like a massive violation of KISS. For a start, I don't see the benefit of CastTo and CastTo&lt;T&gt;. It seems to me that they could be eliminated by tweaking the wrapped conversion methods to work more like int.TryParse with two return values: one to say whether the conversion succeeded, and the other to tell you what the result was. This doesn't necessarily need to use the same pattern of bool return value and out parameter for the result: it could use Tuple and C# 7's tuple unwrapping, for example. But it would simplify the 57 lines of code in the question to 19:

public static T To&lt;T&gt;(this object @this)
{
    if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
    {
        if (@this is string actualStringValue &amp;&amp; _tryCastStringToDateTime(actualStringValue, out var result))
            return result;
    }

    else if (typeof(T) == typeof(bool) || typeof(T) == typeof(bool?))
    {
        if (@this is string actualStringValue &amp;&amp; _tryCastStringToBoolean(actualStringValue, out var result))
            return result;

        else if (@this is int actualIntegerValue &amp;&amp; _tryCastIntegerToBoolean(actualIntegerValue, out result))
            return result;
    }

    return (T) Convert.ChangeType(@this, typeof(T));
}




However, that code still raises red flags. There are situations where you have no choice but to use == typeof(...), but they are rare and mainly related to serialisation. Normally it's a sign that the code should be refactored. This method seems to be actively fighting against the type system. So I would agree completely with the person who told you that it's an abuse of generics. Consider also that if you expose the parse methods as

public static bool ToBool(this string str) { ... }
public static bool ToBool(this int i) { ... }
public static bool ToBool(this object obj)
{
    if (obj is string str) return ToBool(str);
    if (obj is int i) return ToBool(i);
    return (bool)Convert.ChangeType(obj, typeof(bool));
}


then in many actual use cases the compiler will be able to bind directly to the more specific method and skip the runtime checks.

(NB Code not tested, may have compile-time errors, but the principle is the important thing).