Dynamically force a primitive type from one to another?

I am working on a rather complicated problem. At a very high level, I have an object that is primitive, and I need to force it to another primitive type in C #. Values and types are determined at runtime.

I tried something like this (my code is more complex, this demonstrates the problem):

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

This works for a while, except in the case (as indicated above) where overflow or underflow occurs.

I want forcing to happen (instead of converting). In this case, I would just like to: "(int) 0x8ba9dc90" be "(ulong) 0x8ba9dc90". Like float: if value = "(float) -32.01" and "t" is "UInt64", I want the result to be "0xffffffffffffffffffe0". This is exactly what you get when you run "unchecked {ulong u = (ulong) (double) -32.01;}"

Is there a way to do this, or am I stuck in writing a custom converter?

(Yes, I understand that it is a strange thing to try to do this. This is very dynamic code, and I am trying to make coercion in overriding DynamicObject.TryConvert. I also perfectly understand that there are many cases that will drop data using butt applications, etc. This is perfectly fine in my application, I just can't figure out how to write this without a giant nested switch statement.)

EDIT: To be clear, my function looks something like this:

 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 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
source share
1 answer

You can use LINQ expressions for this conversion. This article explains how.

The basic idea is to construct a LINQ expression equivalent to a cast expression.

 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(); 

Now you can call conv and pass it an object , wrapping the value of the original type; it will return you a forced value. This code will also receive your own type conversions (for your own types, not for primitives). If necessary, you can add more conversions between them by increasing the nesting level of your Expression.Convert objects.

+4
source

Source: https://habr.com/ru/post/1433186/


All Articles