Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Compact Framework上使用System.Linq.Expressions的InvalidCastException_C#_.net_Linq_Compact Framework - Fatal编程技术网

C# 在Compact Framework上使用System.Linq.Expressions的InvalidCastException

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

我正在使用db4o项目中的
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
    重载之一创建的
  • 出于兴趣,第二个代码示例中的
    InvalidCastException
    是.Net Compact Framework中的错误,还是该代码试图执行.Net CF不支持的操作
值得一提的是,ILDASM在第一个代码示例中给出了
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