我正在研究一个相当棘手的问题。在非常高的层次上,我有一个原始的对象,我需要在C#中将它强制转换为不同的原始类型。值和类型在运行时确定。
我大致尝试了这个(我的代码更复杂,这证明了问题):
object value = (int)0x8ba9dc90;
Type t = typeof(UInt64);
object result = Convert.ChangeType(value, t);
除了在发生上溢或下溢的情况下(如上所述),这种情况有时会起作用。
我想要发生的事情是强制(而不是转换)会发生。在这种情况下,我只是喜欢"(int)0x8ba9dc90"成为"(ulong)0x8ba9dc90"。与浮点数相似:如果值="(浮动)-32.01"和" t"是" UInt64",我希望结果是" 0xffffffffffffffe0"。这正是你跑步时得到的"未经检查{ulong u =(ulong)(double)-32.01; }"
有没有办法做到这一点,或者我是不是写了自定义转换器?
(是的,我意识到这是一个奇怪的事情。这都是高度动态的代码,我试图在DynamicObject.TryConvert覆盖中进行强制。我也完全知道有一个很多情况下,这会通过向下转换等方式丢弃数据。这在我的应用程序中完全没问题。我只是无法在没有巨大的嵌套switch语句的情况下弄清楚如何写这个。)
编辑:要明确我的功能看起来像这样:
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type.IsPrimitive && m_type.IsPrimitive)
{
// m_type is System.Type, which is m_value's current type.
// m_value is System.Object, contains a primitive value.
// binder.Type is the System.Type I need to coerce m_value into.
result = Convert.ChangeType(m_value, binder.Type);
return true;
}
result = null;
return false;
}
答案 0 :(得分:4)
您可以使用LINQ表达式执行此转换。 This article解释了如何。
基本思想是构造一个等同于强制转换表达式的LINQ表达式。
ParameterExpression convParameter = Expression.Parameter(typeof(object), "val");
var conv = (Func<object,object>)Expression.Lambda(
Expression.Convert(
Expression.Convert(
Expression.Convert(
convParameter
, fromType
)
, targetType
)
, typeof(object)
)
, convParameter
).Compile();
现在你可以调用conv
并传递object
包装原始类型的值;它会将强制值返还给您。此代码也将获取您的自定义类型转换(对于您自己的类型,而不是基元)。如有必要,您可以通过提高Expression.Convert
对象的嵌套级别,在两者之间添加更多转化。