动态强制原始类型从一个到另一个?

时间:2012-09-09 01:35:23

标签: c# type-conversion

我正在研究一个相当棘手的问题。在非常高的层次上,我有一个原始的对象,我需要在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;
}

1 个答案:

答案 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对象的嵌套级别,在两者之间添加更多转化。