The problem with implicit / explicit conversions is that they are solved at compile time. So (as far as I know) there is no simple runtime check. However, the dynamic implementation will select them and call them at runtime. You can (as if ugly) create a class that will try to perform the conversion, catch an exception if it does not work, and tell whether it passed it or not:
public class TypeConverterChecker<TFrom, TTo> { public bool CanConvert { get; private set; } public TypeConverterChecker(TFrom from) { try { TTo to = (TTo)(dynamic)from; CanConvert = true; } catch { CanConvert = false; } } }
For some classes, such as:
public class Foo { public static implicit operator Bar(Foo foo) { return new Bar(); } public static implicit operator Foo(Bar bar) { return new Foo(); } } public class Bar { } public class Nope { }
Using:
Console.WriteLine((new TypeConverterChecker<Foo, Bar>(new Foo())).CanConvert); //True Console.WriteLine((new TypeConverterChecker<Bar, Foo>(new Bar())).CanConvert); //True Console.WriteLine((new TypeConverterChecker<Foo, Nope>(new Foo())).CanConvert); //False
And with the types you checked:
Console.WriteLine((new TypeConverterChecker<Int16, Decimal>(0)).CanConvert); //True Console.WriteLine((new TypeConverterChecker<UInt16, Decimal>(0)).CanConvert); //True Console.WriteLine((new TypeConverterChecker<UInt16, Int64>(0)).CanConvert); //True Console.WriteLine((new TypeConverterChecker<UInt16, Double>(0)).CanConvert); //True Console.WriteLine((new TypeConverterChecker<UInt16, String>(0)).CanConvert); //False
Now I can imagine that this can be changed to be more efficient (cache the result statically, so subsequent requests for the same combination TFrom, TTo should not try to convert, because value types ignore the need for an input instance (just use default(TFrom) ), etc., but it should give you a TFrom from should be noted that you should not pass null for TFrom from , since all null will pass (unless it is a value type)
You can also add a second try/catch to try using the Convert.ChangeType method and see if the types are defined by IConvertable implementations that can be used. (you can save this as a separate boolean flag so that you know what type of conversion you need to perform later)
EDIT: If you don't know the types at compile time, you can use a little reflection to still use the conversion checker:
public static class TypeConverterChecker { public static bool Check(Type fromType, Type toType, object fromObject) { Type converterType = typeof(TypeConverterChecker<,>).MakeGenericType(fromType, toType); object instance = Activator.CreateInstance(converterType, fromObject); return (bool)converterType.GetProperty("CanConvert").GetGetMethod().Invoke(instance, null); } }
Your use might look like this:
object unknownObject = new Foo(); Type targetType = typeof(Bar); Type sourceType = unknownObject.GetType(); Console.WriteLine(TypeConverterChecker.Check(sourceType, targetType, unknownObject)); targetType = typeof(Nope); Console.WriteLine(TypeConverterChecker.Check(sourceType, targetType, unknownObject));