简体   繁体   English

用于转换数值的表达式:System.InvalidCastException:> 无法将“System.Int32”类型的 object 转换为“System.Int64”类型

[英]Expression to convert numeric values: System.InvalidCastException: > Unable to cast object of type 'System.Int32' to type 'System.Int64'

I'm trying to create an expression to convert some numeric values.我正在尝试创建一个表达式来转换一些数值。 Here is what I have tried:这是我尝试过的:

public object ConvertValue(object value, Type targetType) {
    var parameter = Expression.Parameter(typeof(object), "p"); // "p"
    var convert = Expression.Convert(parameter, targetType); // Convert(p, Int64)
    var targetConvert = Expression.Convert(convert, typeof(object)); // Convert(Convert(p, Int64), Object)
    var lambda = Expression.Lambda<Func<object,object>>(targetConvert, parameter); // p => Convert(Convert(p, Int64), Object)
    var method = lambda.Compile();
    var result = method(value); // HERE I GET THE ERROR!
    return result;
}

But when I call it, as this simple test:但是当我调用它时,就像这个简单的测试:

[Fact]
public void TestConvert() {
    var result = ConvertValue(23, typeof(long));
    Assert.Equal(typeof(long), result.GetType());
}

I get the error:我得到错误:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. System.Reflection.TargetInvocationException:调用的目标已引发异常。 ---> System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Int64'. ---> System.InvalidCastException:无法将“System.Int32”类型的 object 转换为“System.Int64”类型。
at lambda_method(Closure, Object ) bla bla bla...在 lambda_method(关闭,Object)bla bla bla ...

Any idea what's happening here and what Int32 cannot be cast to Int64 ?知道这里发生了什么以及Int32不能转换为Int64吗? Thanks in advance.提前致谢。

The following takes advantage of Convert.ChangeType to provide more flexibility with the conversions.下面利用Convert.ChangeType为转换提供更大的灵活性。

The code comments document what is being done.代码注释记录了正在做什么。

public object ConvertValue(object value, Type targetType){
    var valueType = value.GetType();
    // Func<TValue,TTarget>
    var delegateType = typeof(Func<,>).MakeGenericType(valueType, targetType);
    var convert = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
    // TValue p
    var parameter = Expression.Parameter(valueType, "p");
    // Convert.ChangeType(Convert(p), targetType);
    var changeType = Expression.Call(convert, Expression.Convert(parameter, typeof(object)), Expression.Constant(targetType));
    // (TTarget)Convert.ChangeType(Convert(p), targetType);
    var body = Expression.Convert(changeType, targetType);
    //Func<TValue,TTarget> = TValue p => (TTarget)Convert.ChangeType(Convert(p), targetType);
    var lambda = Expression.Lambda(delegateType, body, parameter);
    var method = lambda.Compile();
    var result = method.DynamicInvoke(value);
    return result;
}

The following basic tests all passed when exercised以下基本测试在运动时全部通过

[TestMethod]
public void Should_Convert_Int_To_Long() {
    var expected = typeof(long);
    var actual = ConvertValue(23, expected);
    Assert.AreEqual(expected, actual.GetType());
}

[TestMethod]
public void Should_Convert_Long_To_Int() {
    var expected = typeof(int);
    var actual = ConvertValue((long)23, expected);
    Assert.AreEqual(expected, actual.GetType());
}

[TestMethod]
public void Should_Convert_String_To_Long() {
    var expected = typeof(long);
    var actual = ConvertValue("23", expected);
    Assert.AreEqual(expected, actual.GetType());
}

[TestMethod]
public void Should_Convert_String_To_Int() {
    var expected = typeof(int);
    var actual = ConvertValue("23", expected);
    Assert.AreEqual(expected, actual.GetType());
}

What you try to do is (int64)(object)23 and it won't work because 23 is of type int32 .您尝试做的是(int64)(object)23 ,它不起作用,因为23int32 You can pass 23L literal and it'll work:您可以通过23L文字,它会工作:

ConvertValue(23L, typeof(long));

To make your code work, you need to call convert from int32 to int64 after unboxing:为了使您的代码正常工作,您需要在拆箱后调用 convert from int32 to int64

public static object ConvertValue(object value, Type targetType) {
    var parameter = Expression.Parameter(typeof(object), "p"); // "p"
    var convert = Expression.Convert(Expression.Convert(parameter, value.GetType()), targetType); // Convert(p, Int64)
    var targetConvert = Expression.Convert(convert, typeof(object)); // Convert(Convert(p, Int64), Object)
    var lambda = Expression.Lambda<Func<object,object>>(targetConvert, parameter); // p => Convert(Convert(p, Int64), Object)
    var method = lambda.Compile();
    var result = method(value);
    return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 EF Core RemoveRange System.InvalidCastException:无法将“System.Int32”类型的 object 转换为“System.Int64”类型 - EF Core RemoveRange System.InvalidCastException : Unable to cast object of type 'System.Int32' to type 'System.Int64' System.InvalidCastException:无法将“System.Double”类型的 object 转换为代码中的“System.Int32”类型 - System.InvalidCastException: Unable to cast object of type 'System.Double' to type 'System.Int32' in code 错误:System.InvalidCastException:无法将“System.Byte”类型的对象转换为“System.Int32”类型 - Error: System.InvalidCastException: Unable to cast object of type 'System.Byte' to type 'System.Int32' C#:无法将“System.Int64”类型的对象转换为“System.Int32”类型 - C#: Unable to cast object of type 'System.Int64' to type 'System.Int32' Entityframework 核心无法将类型为“System.Int32”的 object 转换为类型“System.Int64” - Entityframework Core Unable to cast object of type 'System.Int32' to type 'System.Int64' 无法将 System.Int64 类型的 object 转换为 System.Int32 类型 - Unable to cast object of type System.Int64 to type System.Int32 无法将类型为“ System.Int64”的对象转换为类型为“ System.Int32”的对象 - Unable to cast object of type 'System.Int64' to type 'System.Int32' Expression.Convert:'System.Int64'类型的对象无法转换为'System.Int32'类型 - Expression.Convert: Object of type 'System.Int64' cannot be converted to type 'System.Int32' LINQ ToDictionary System.InvalidCastException:&#39;无法将类型为&#39;System.Int32&#39;的对象强制转换为类型为&#39;System.String&#39;。 - LINQ ToDictionary System.InvalidCastException: 'Unable to cast object of type 'System.Int32' to type 'System.String'.' 从物化的“System.Int32”类型到“System.Int64”类型的指定强制转换无效 - The specified cast from a materialized 'System.Int32' type to the 'System.Int64' type is not valid
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM