我最終手動處理原始類型場景。不是很優雅,但它的作品。
我還添加了額外的邏輯來處理可爲空的類型和枚舉。
我爲用戶定義的類型場景重用Poke's code。
public class AvailableCastChecker
{
public static bool CanCast(Type from, Type to)
{
if (from.IsAssignableFrom(to))
{
return true;
}
if (HasImplicitConversion(from, from, to)|| HasImplicitConversion(to, from, to))
{
return true;
}
List<Type> list;
if (ImplicitNumericConversions.TryGetValue(from, out list))
{
if (list.Contains(to))
return true;
}
if (to.IsEnum)
{
return CanCast(from, Enum.GetUnderlyingType(to));
}
if (Nullable.GetUnderlyingType(to) != null)
{
return CanCast(from, Nullable.GetUnderlyingType(to));
}
return false;
}
// https://msdn.microsoft.com/en-us/library/y5b434w4.aspx
static Dictionary<Type,List<Type>> ImplicitNumericConversions = new Dictionary<Type, List<Type>>();
static AvailableCastChecker()
{
ImplicitNumericConversions.Add(typeof(sbyte), new List<Type> {typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(byte), new List<Type> { typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(short), new List<Type> { typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(ushort), new List<Type> { typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(int), new List<Type> { typeof(long), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(uint), new List<Type> { typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(long), new List<Type> { typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(char), new List<Type> { typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) });
ImplicitNumericConversions.Add(typeof(float), new List<Type> { typeof(double) });
ImplicitNumericConversions.Add(typeof(ulong), new List<Type> { typeof(float), typeof(double), typeof(decimal) });
}
static bool HasImplicitConversion(Type definedOn, Type baseType, Type targetType)
{
return definedOn.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(mi => mi.Name == "op_Implicit" && mi.ReturnType == targetType)
.Any(mi =>
{
ParameterInfo pi = mi.GetParameters().FirstOrDefault();
return pi != null && pi.ParameterType == baseType;
});
}
}
只是一個提示:看看[隱式類型轉換運算符](https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx)。我想應該有一種方法來通過反思找到隱式操作符... – elgonzo
您能否詳細談談您試圖用結果完成什麼目標?我過去遇到類似的問題,意識到它幾乎必須看起來像什麼CliveDM [鏈接](https://github.com/CYJB/Cyjb/blob/f4424c4f81cacd09e9ce5d202a03b0c121c09ac2/Cyjb/TypeExt.cs)[下面](http://stackoverflow.com/a/32025388/1083771),並決定只調用[Convert.ChangeType](https://msdn.microsoft.com/en-us/library/dtb69x08.aspx)並處理例外。我意識到這可能不是一個可行的解決方案,但也許有類似的解決方法。 –