Given Type a and Type b, how can I, at runtime, determine whether there's an implicit conversion from a to b?
If that doesn't make sense, consider the following method:
public PropertyInfo GetCompatibleProperty<T>(object instance, string propertyName) { var property = instance.GetType().GetProperty(propertyName); bool isCompatibleProperty = !property.PropertyType.IsAssignableFrom(typeof(T)); if (!isCompatibleProperty) throw new Exception("OH NOES!!!"); return property; }
And here's the calling code that I want to work:
// Since string.Length is an int property, and ints are convertible // to double, this should work, but it doesn't. :-( var property = GetCompatibleProperty<double>("someStringHere", "Length");
Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.
Implicit Type Conversion is also known as 'automatic type conversion'. It is done by the compiler on its own, without any external trigger from the user. It generally takes place when in an expression more than one data type is present.
In implicit typecasting, the conversion involves a smaller data type to the larger type size. For example, the byte datatype implicitly typecast into short, char, int, long, float, and double. The process of converting the lower data type to that of a higher data type is referred to as Widening.
Implicit type conversion also known as automatic type conversion is carried out by the compiler without the need for a user-initiated action. It takes place when an expression of more than one data type is present which in such an instance type conversion takes place to avoid data loss.
Note that IsAssignableFrom
does NOT solve your problem. You have to use Reflection like so. Note the explicit need to handle the primitive types; these lists are per §6.1.2 (Implicit numeric conversions) of the specification.
static class TypeExtensions { static Dictionary<Type, List<Type>> dict = new Dictionary<Type, List<Type>>() { { typeof(decimal), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char) } }, { typeof(double), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float) } }, { typeof(float), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float) } }, { typeof(ulong), new List<Type> { typeof(byte), typeof(ushort), typeof(uint), typeof(char) } }, { typeof(long), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(char) } }, { typeof(uint), new List<Type> { typeof(byte), typeof(ushort), typeof(char) } }, { typeof(int), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(char) } }, { typeof(ushort), new List<Type> { typeof(byte), typeof(char) } }, { typeof(short), new List<Type> { typeof(byte) } } }; public static bool IsCastableTo(this Type from, Type to) { if (to.IsAssignableFrom(from)) { return true; } if (dict.ContainsKey(to) && dict[to].Contains(from)) { return true; } bool castable = from.GetMethods(BindingFlags.Public | BindingFlags.Static) .Any( m => m.ReturnType == to && (m.Name == "op_Implicit" || m.Name == "op_Explicit") ); return castable; } }
Usage:
bool b = typeof(A).IsCastableTo(typeof(B));
Implicit conversions you'll need to consider:
I assume you're looking for the latter. You'll need to write something resembling a compiler to cover all of them. Notable is that System.Linq.Expressions.Expression didn't attempt this feat.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With