由于A型和B型我怎么能在运行时,判断是否有从的隐式转换到b?
如果说没有意义,可以考虑下面的方法:
公开的PropertyInfo GetCompatibleProperty< T>(对象实例,字符串propertyName的)
{
VAR属性= instance.GetType()的getProperty(propertyName的)。
!布尔isCompatibleProperty = property.PropertyType.IsAssignableFrom(typeof运算(T));
(!isCompatibleProperty),如果抛出新的异常(OH反对者占!!!);
返回财产;
}
这就是我想要的工作调用code:
//由于string.length减是一个int属性,和整数可兑换
//翻番,这应该工作,但事实并非如此。 :-(
VAR属性= GetCompatibleProperty<双>(someStringHere,长度);
解决方案
注意 IsAssignableFrom
不解决您的问题。你必须使用反射像这样。请注意,明确需要处理的基本数据类型;这些名单是每§6.1.2规范(隐式数字转换)。
静态类TypeExtensions {
静态字典<类型,列表和LT;类型>>字典=新字典<类型,列表和LT;类型>>(){
{typeof运算(十进制),新的名单,其中,类型和GT; {typeof运算(为sbyte)的typeof(字节)的typeof(短)的typeof(USHORT)的typeof(INT)的typeof(UINT)的typeof(长)的typeof(ULONG)的typeof(炭)}},
{typeof运算(双),新的名单,其中,类型和GT; {typeof运算(为sbyte)的typeof(字节)的typeof(短)的typeof(USHORT)的typeof(INT)的typeof(UINT)的typeof(长)的typeof(ULONG)的typeof(炭),typeof运算(浮点) }},
{typeof运算(浮点),新的名单,其中,类型和GT; {typeof运算(为sbyte)的typeof(字节)的typeof(短)的typeof(USHORT)的typeof(INT)的typeof(UINT)的typeof(长)的typeof(ULONG)的typeof(炭),typeof运算(浮点) }},
{typeof运算(ULONG),新的名单,其中,类型和GT; {typeof运算(字节)的typeof(USHORT)的typeof(UINT)的typeof(炭)}},
{typeof运算(长),新的名单,其中,类型和GT; {typeof运算(为sbyte)的typeof(字节)的typeof(短)的typeof(USHORT)的typeof(INT)的typeof(UINT)的typeof(炭)}},
{typeof运算(UINT),新的名单,其中,类型和GT; {typeof运算(字节)的typeof(USHORT)的typeof(炭)}},
{typeof运算(INT),新的名单,其中,类型和GT; {typeof运算(为sbyte)的typeof(字节)的typeof(短)的typeof(USHORT)的typeof(炭)}},
{typeof运算(USHORT),新的名单,其中,类型和GT; {typeof运算(字节)的typeof(炭)}},
{typeof运算(短),新的名单,其中,类型和GT; {的typeof(字节)}}
};
公共静态布尔IsCastableTo(这种类型的,类型为){
如果(to.IsAssignableFrom(从)){
返回true;
}
如果(dict.ContainsKey(到)及和放大器;快译通[来]。载(从)){
返回true;
}
布尔浇注料= from.GetMethods(BindingFlags.Public | BindingFlags.Static)
。任何(
M => m.ReturnType ==到&安培;&安培;
(m.Name ==op_Implicit||
m.Name ==op_Explicit)
);
返回浇注料;
}
}
用法:
布尔B = typeof运算(A).IsCastableTo(typeof运算(B));
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");
解决方案
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));