C# 在Compact Framework上使用System.Linq.Expressions的InvalidCastException
我正在使用db4o项目中的C# 在Compact Framework上使用System.Linq.Expressions的InvalidCastException,c#,.net,linq,compact-framework,C#,.net,Linq,Compact Framework,我正在使用db4o项目中的System.Linq.Expressions实现。该代码在.Net Compact Framework 3.5上的Windows Mobile 6上运行。它被提到,来源是。我已经用了一段时间了,它运行得很好。但是,我现在在尝试转换将引用类型返回到表达式树的Func委托时遇到了InvalidCastException。InvalidCastException是由.Net Compact Framework中的一个bug引起的。我还有第二个代码示例,详细说明了这个bug
System.Linq.Expressions
实现。该代码在.Net Compact Framework 3.5上的Windows Mobile 6上运行。它被提到,来源是。我已经用了一段时间了,它运行得很好。但是,我现在在尝试转换将引用类型返回到表达式树的Func
委托时遇到了InvalidCastException
。InvalidCastException
是由.Net Compact Framework中的一个bug引起的。我还有第二个代码示例,详细说明了这个bug
使用System.Linq.Expressions的InvalidCastException示例
using System;
using System.Linq.Expressions;
class Program
{
static void Main(string[] args)
{
// throws InvalidCastException
Expression<Func<object>> expr = () => new object();
}
}
我使用ILDASM查看了生成的CIL(见下文),结果发现无效转换是从MethodBase
到ConstructorInfo
的转换。此强制转换是必需的,因为通过调用带有ConstructorInfo
类型参数的Expression.New
在lambda的主体中生成了NewExpression
。对于值类型不发生这种情况的原因是,使用了一个类型为type
的参数。(从我的应用程序中的代码中使用ConstructorInfo
参数调用其中一个重载可以很好地工作,顺便说一句,只有当表达式树是由编译器生成的代码构建时才会出现问题。)
由于问题发生在表达式中。New
重载类型为ConstructorInfo
的参数,我尝试更改这些方法,让它们接受MethodBase
的参数,甚至接受object
而不是ConstructorInfo
。但这会产生一个编译错误:
缺少编译器必需的成员
'System.Linq.Expressions.Expression.New'
显然(也有理由)编译器对方法的签名非常挑剔
.Net Compact Framework中的bug示例
以下代码给出了相同的无效强制转换,但未使用自定义的System.Linq.Expressions
(此代码在.Net 3.5上运行良好,但在.Net Compact Framework 3.5上失败):
我的问题(是的,我马上就到了,谢谢你读到这里)
- 我能做些什么来让第一个代码示例工作吗
- 更一般地说,我可以做些什么来从编译器中获取表达式树,其中主体具有
,它们是由带有NewExpressions
参数的ConstructorInfo
重载之一创建的New
- 出于兴趣,第二个代码示例中的
是.Net Compact Framework中的错误,还是该代码试图执行.Net CF不支持的操作InvalidCastException
Main
方法:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 40 (0x28)
.maxstack 2
.locals init ([0] class [System.Linq.Expressions]System.Linq.Expressions.Expression`1<class [System.Core]System.Func`1<object>> expr)
IL_0000: nop
IL_0001: ldtoken method instance void [mscorlib]System.Object::.ctor()
IL_0006: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
IL_000b: castclass [mscorlib]System.Reflection.ConstructorInfo
IL_0010: ldc.i4.0
IL_0011: newarr [System.Linq.Expressions]System.Linq.Expressions.Expression
IL_0016: call class [System.Linq.Expressions]System.Linq.Expressions.NewExpression [System.Linq.Expressions]System.Linq.Expressions.Expression::New(class [mscorlib]System.Reflection.ConstructorInfo,
class [System.Linq.Expressions]System.Linq.Expressions.Expression[])
IL_001b: ldc.i4.0
IL_001c: newarr [System.Linq.Expressions]System.Linq.Expressions.ParameterExpression
IL_0021: call class [System.Linq.Expressions]System.Linq.Expressions.Expression`1<!!0> [System.Linq.Expressions]System.Linq.Expressions.Expression::Lambda<class [System.Core]System.Func`1<object>>(class [System.Linq.Expressions]System.Linq.Expressions.Expression,
class [System.Linq.Expressions]System.Linq.Expressions.ParameterExpression[])
IL_0026: stloc.0
IL_0027: ret
} // end of method Program::Main
.method private隐藏静态void Main(字符串[]args)cil托管
{
.入口点
//代码大小40(0x28)
.maxstack 2
.locals init([0]类[System.Linq.Expressions]System.Linq.Expressions.Expression`1)
IL_0000:没有
IL_0001:ldtoken方法实例无效[mscorlib]系统。对象::.ctor()
IL_0006:调用类[mscorlib]System.Reflection.MethodBase[mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype[mscorlib]System.RuntimeMethodHandle)
IL_000b:castclass[mscorlib]System.Reflection.ConstructorInfo
IL_0010:ldc.i4.0
IL_0011:newarr[System.Linq.Expressions]System.Linq.Expressions.Expression
IL_0016:调用类[System.Linq.Expressions]System.Linq.Expressions.NewExpression[System.Linq.Expressions]System.Linq.Expressions::New(类[mscorlib]System.Reflection.ConstructorInfo,
类[System.Linq.Expressions]System.Linq.Expressions.Expression[]
IL_001b:ldc.i4.0
IL_001c:newarr[System.Linq.Expressions]System.Linq.Expressions.ParameterExpression
IL_0021:调用类[System.Linq.Expressions]System.Linq.Expressions.Expression`1[System.Linq.Expressions]System.Linq.Expressions.Expression::Lambda(类[System.Linq.Expressions]System.Linq.Expressions.Expression,
类[System.Linq.Expressions]System.Linq.Expressions.ParameterExpression[]
IL_0026:stloc.0
IL_0027:ret
}//方法程序结束::Main
为什么要添加mono标记?@knocte:因为System.Linq.Expressions使用的源db4o来自mono项目。这是什么意思?db4o不是托管在mono存储库中的,也从来没有been@knocte:在我的帖子中的第一个链接中,JB Evain写道:“那些优秀的人所做的,仅仅是采用Mono对这个名称空间的实现。”,其中“那些优秀的人”是db4o,“这个名称空间”是System.Linq.Expressions
。我明白我的问题可能与那些只对Mono感兴趣的人无关。但很可能我的问题的解决方案来自Mono(通过添加Mono的一部分,甚至用Mono的一部分替换.Net CF的一部分)。这就是我添加Mono标记的原因。如果他看到的问题是因为他使用的System.Linq.Expressions
代码中的错误,这与Mono无关。我并不是说这就是问题所在,但如果是的话,那就非常相关了。
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
// Get method handle of parameterless constructor
Type type = typeof(object);
ConstructorInfo constructorInfo0 = type.GetConstructor(new Type[0]);
RuntimeMethodHandle runtimeMethodHandle = constructorInfo0.MethodHandle;
// Get method from method handle
MethodBase methodBase =
MethodBase.GetMethodFromHandle(runtimeMethodHandle);
// Casting back to ConstructorInfo throws InvalidCastException on .Net CF
ConstructorInfo constructorInfo1 = (ConstructorInfo)methodBase;
}
}
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 40 (0x28)
.maxstack 2
.locals init ([0] class [System.Linq.Expressions]System.Linq.Expressions.Expression`1<class [System.Core]System.Func`1<object>> expr)
IL_0000: nop
IL_0001: ldtoken method instance void [mscorlib]System.Object::.ctor()
IL_0006: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
IL_000b: castclass [mscorlib]System.Reflection.ConstructorInfo
IL_0010: ldc.i4.0
IL_0011: newarr [System.Linq.Expressions]System.Linq.Expressions.Expression
IL_0016: call class [System.Linq.Expressions]System.Linq.Expressions.NewExpression [System.Linq.Expressions]System.Linq.Expressions.Expression::New(class [mscorlib]System.Reflection.ConstructorInfo,
class [System.Linq.Expressions]System.Linq.Expressions.Expression[])
IL_001b: ldc.i4.0
IL_001c: newarr [System.Linq.Expressions]System.Linq.Expressions.ParameterExpression
IL_0021: call class [System.Linq.Expressions]System.Linq.Expressions.Expression`1<!!0> [System.Linq.Expressions]System.Linq.Expressions.Expression::Lambda<class [System.Core]System.Func`1<object>>(class [System.Linq.Expressions]System.Linq.Expressions.Expression,
class [System.Linq.Expressions]System.Linq.Expressions.ParameterExpression[])
IL_0026: stloc.0
IL_0027: ret
} // end of method Program::Main