How to tell if Type A is implicitly convertible to Type B(如何判断 A 型是否可隐式转换为 B 型)
问题描述
给定类型 a 和类型 b,我如何在运行时确定是否存在从 a 到 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");
推荐答案
请注意,IsAssignableFrom 并不能解决您的问题.你必须像这样使用反射.注意处理原始类型的明确需要;这些列表符合规范的第 6.1.2 节(隐式数字转换).
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;
}
}
用法:
bool b = typeof(A).IsCastableTo(typeof(B));
这篇关于如何判断 A 型是否可隐式转换为 B 型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何判断 A 型是否可隐式转换为 B 型
基础教程推荐
- C# 从 List<List<int>> 中删除重 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
- Moq It.Is<>不匹配 2022-01-01
- WPF 模态进度窗口 2022-01-01
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- .NET SerialPort DataReceived 事件未触发 2022-01-01
