4

我正在研究一个相当棘手的问题。在非常高的层次上,我有一个原始对象,我需要将它强制转换为 C# 中的不同原始类型。值和类型在运行时确定。

我大致尝试了这个(我的代码更复杂,这说明了问题):

object value = (int)0x8ba9dc90;
Type t = typeof(UInt64);
object result = Convert.ChangeType(value, t);

这在某些时候有效,除非在(如上所述)会发生上溢或下溢的情况下。

想要发生的是强制(而不是转换)会发生。在这种情况下,我只是希望“(int)0x8ba9dc90”为“(ulong)0x8ba9dc90”。与浮点数类似:如果 value = "(float)-32.01" 且 "t" 为 "UInt64",我希望结果为 "0xffffffffffffffe0"。这正是你运行“unchecked { 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;
}
4

1 回答 1

4

您可以使用 LINQ 表达式进行此转换。这篇文章解释了如何。

基本思想是构造一个与强制转换表达式等效的 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对象的嵌套级别在两者之间添加更多转换。

于 2012-09-09T01:55:52.617 回答