[英]Test if Convert.ChangeType will work between two types
这是关于使用反射转换值的问题的后续行动。 将某种类型的对象转换为另一种类型可以这样做:
object convertedValue = Convert.ChangeType(value, targetType);
给定两个Type实例(比如FromType和ToType),有没有办法测试转换是否成功?
我可以写一个像这样的扩展方法:
public static class TypeExtensions
{
public static bool CanChangeType(this Type fromType, Type toType)
{
// what to put here?
}
}
编辑:这就是我现在所拥有的。 丑陋,但我还没有看到另一种方式......
bool CanChangeType(Type sourceType, Type targetType)
{
try
{
var instanceOfSourceType = Activator.CreateInstance(sourceType);
Convert.ChangeType(instanceOfSourceType, targetType);
return true; // OK, it can be converted
}
catch (Exception ex)
{
return false;
}
我刚刚遇到同样的问题,我使用Reflector来查看ChangeType的源代码。 ChangeType在3种情况下抛出异常:
检查完3个后,保证可以转换。 因此,您可以通过简单地自行检查这3个内容来节省大量性能并删除try {} / catch {}块:
public static bool CanChangeType(object value, Type conversionType)
{
if (conversionType == null)
{
return false;
}
if (value == null)
{
return false;
}
IConvertible convertible = value as IConvertible;
if (convertible == null)
{
return false;
}
return true;
}
检查反射器中的Convert.ChangeType方法我在静态构造函数中找到了这个:
ConvertTypes = new Type[] {
typeof(Empty), typeof(object), typeof(DBNull), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal),
typeof(DateTime), typeof(object), typeof(string)
};
最后,此方法只是检查源是否正在实现IConvertible,或者目标是否是上面的ConvertTypes之一。 所以你的方法应该看起来像这样(非常粗糙):
return (ConvertTypes.Contains(toType) || typeof(IConvertible).IsAssignableFrom(fromType));
根据我在这两个问题上已经回答的问题,我想出了这个问题,(需要c#7)
public static object ChangeType(object value, Type conversion)
{
var type = conversion;
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return null;
}
type = Nullable.GetUnderlyingType(type);
}
return Convert.ChangeType(value, type);
}
public static (bool IsSuccess, object Value) TryChangeType(object value, Type conversionType)
{
(bool IsSuccess, object Value) response = (false, null);
var isNotConvertible =
conversionType == null
|| value == null
|| !(value is IConvertible)
|| !(value.GetType() == conversionType);
if (isNotConvertible)
{
return response;
}
try
{
response = (true, ChangeType(value, conversionType));
}
catch (Exception)
{
response.Value = null;
}
return response;
}
}
生产代码示例:
public Item()
{
foreach (var pinfo in GetType().GetProperties())
{
object value = 0;
var response = ReflectionHelpers.TryChangeType(value, pinfo.PropertyType);
if(response.IsSuccess)
{
pinfo.SetValue(this, response.Value);
}
}
}
这将启动0的所有可能属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.