CompileToMethod 无法编译常量“<some value>”,因为它是一个非常重要的值,例如活动对象
CompileToMethod cannot compile constant '<some value>' because it is a non-trivial value, such as a live object
我正在尝试使用名为 EvaluateOnCondition 的方法创建具有 Reflection.Emit 的类型。我用 Linq Expressions 生成方法的主体,我想将表达式的 IL 注入 EvaluateOnCondition 使用 CompileToMethod 方法 LambdaExpression,但是当我执行 CompileToMethod 方法时,我得到了以下错误:
CompileToMethod cannot compile constant 'some value' because it is a
non-trivial value, such as a live object. Instead, create an
expression tree that can construct this value.
这就是我想要做的:
MethodBuilder evaluateOnCondition = tb.DefineMethod("EvaluateOnCondition", MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new[] { typeof(object), typeof(object) });
onCondition.CompileToMethod(evaluateOnCondition); // throw the error
onCondition 变量是一个 LambdaExpression,是用 Linq 表达式创建的比较条件,表示以下伪代码:obj1.prop1 == obj2.prop1
这是我的 StackTrace:
at System.Linq.Expressions.Compiler.BoundConstants.EmitCacheConstants(LambdaCompiler lc)
at System.Linq.Expressions.Compiler.LambdaCompiler..ctor(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method)
at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, MethodBuilder method, DebugInfoGenerator debugInfoGenerator)
at System.Linq.Expressions.LambdaExpression.CompileToMethodInternal(MethodBuilder method, DebugInfoGenerator debugInfoGenerator)
at System.Linq.Expressions.LambdaExpression.CompileToMethod(MethodBuilder method)
at Integra.Space.Language.Runtime.LanguageTypeBuilder.CreateEqualsMethod(TypeBuilder tb, Type parentType, Type typeOtherSource, Boolean isSecondSource, LambdaExpression onCondition) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\TypeBuilders\LanguageTypeBuilder.cs:line 343
at Integra.Space.Language.Runtime.LanguageTypeBuilder.CreateTypeBuilder(List`1 listOfFields, Type parentType, Boolean overrideGetHashCodeMethod, Boolean overrideEquals, Type typeOtherSource, Boolean isSecondSource, LambdaExpression onCondition) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\TypeBuilders\LanguageTypeBuilder.cs:line 165
at Integra.Space.Language.Runtime.LanguageTypeBuilder.CompileExtractedEventDataComparerTypeForJoin(Type parentType, Type typeOfTheOtherSource, Boolean isSecondSource, LambdaExpression onCondition) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\TypeBuilders\LanguageTypeBuilder.cs:line 92
at Integra.Space.Language.Runtime.ObservableConstructor.CreateProjectionExpression(PlanNode plans) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 3033
at Integra.Space.Language.Runtime.ObservableConstructor.CreateExpressionNode(PlanNode actualNode, Expression leftNode, Expression rightNode) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 358
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 304
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 313
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 299
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 299
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 313
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 313
at Integra.Space.Language.Runtime.ObservableConstructor.CreateObservableJoin(PlanNode actualNode) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 936
onCondition 变量的调试视图
.Block(System.Boolean $variable) {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the equal operation '==': ")
} .Else {
.Default(System.Void)
};
$variable = (System.Object).Block(System.Object $variable) {
.If (.Constant<System.Reflection.RuntimePropertyInfo>(System.Object _adapter_Name) == null) { // 12 line
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_0._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var1) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 162 con t1.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 162, Instruction: t1.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var1)
}
}
};
$variable
} == (System.Object).Block(System.Object $variable) {
.If (.Constant<System.Reflection.RuntimePropertyInfo>(System.Object _adapter_Name) == null) {
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_1._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var2) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 188 con t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 188, Instruction: t2.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var2)
}
}
};
$variable
};
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the equal operation")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var3) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("Error con la expresion de igualdad en la linea: 0 columna: 167 con t1.@event.Adapter.Name == t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 167, Instruction: t1.@event.Adapter.Name == t2.@event.Adapter.Name, Error: RE43: Error with the equal operation '=='",
$var3)
}
};
$variable
}
我怀疑是内核的这一行抛出了错误
顺便说一句:C# 中的 非平凡值 是什么?
我该如何解决这个问题?
如果您需要更多信息,请告诉我
我解决了这个问题,如果您想使用 CompileToMethod 方法将表达式转换为方法的 IL 主体,基本上您不能将反射用于表达式树.现在这是我的 onCondition 调试视图:
.Block(System.Boolean $variable) {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the equal operation '==': ")
} .Else {
.Default(System.Void)
};
$variable = (System.Object).Block(System.Object $variable) {
.If (True == False) { // 12 line
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_0._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var1) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 162 con t1.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 162, Instruction: t1.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var1)
}
}
};
$variable
} == (System.Object).Block(System.Object $variable) {
.If (True == False) {
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_1._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var2) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 188 con t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 188, Instruction: t2.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var2)
}
}
};
$variable
};
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the equal operation")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var3) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("Error con la expresion de igualdad en la linea: 0 columna: 167 con t1.@event.Adapter.Name == t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 167, Instruction: t1.@event.Adapter.Name == t2.@event.Adapter.Name, Error: RE43: Error with the equal operation '=='",
$var3)
}
};
$variable
}
你可以看到第 12 行我删除了反射的使用以获得 属性 _adapter_Name.
What is non-trivial value in C#? How could I fix this?*
一般null
, bool
, char
, sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, float
, double
, decimal
, string
, Type
, MethodBase
都可以。其他都不是。
从VariableBinder.VisitConstant
开始就可以看到:
if (ILGen.CanEmitConstant(node.Value, node.Type))
{
return node;
}
this._constants.Peek().AddReference(node.Value, node.Type);
转到 AddReference
是不好的,并且会在长时间 运行 中导致您看到的异常。
然后您可以查看 ILGen.CanEmitConstant
并查看已完成的测试。
为什么会这样?因为你正试图在一个方法中编译一个对象。虽然如果您使用 LambdaExpression.Compile()
这通常是可能的,因为对象并没有真正保存在方法中,而只是对内存中对象的引用,如果您使用 CompileToMethod()
. NET 必须能够在方法内保存对象的副本,因为 CompileToMethod()(和 MethodBuilder
/TypeBuilder
/AssemblyBuilder
)能够生成新的 dll。这些 dll 可以在 machines/loaded 天后与其他 machines/loaded 共享(它们是 "normal" dll),因此不能保证它们仅在当前程序的生命周期内是 运行。为此,.NET 需要序列化对象,然后在调用方法时反序列化它。但这不受支持。显然,这不会发生在某些原始类型(我会注意到并非所有 .NET 原始类型都受支持。缺少 IntPtr
和 UIntPtr
)以及一些特殊类型,如 Type
(在 .NET 中有特殊处理)。
我正在尝试使用名为 EvaluateOnCondition 的方法创建具有 Reflection.Emit 的类型。我用 Linq Expressions 生成方法的主体,我想将表达式的 IL 注入 EvaluateOnCondition 使用 CompileToMethod 方法 LambdaExpression,但是当我执行 CompileToMethod 方法时,我得到了以下错误:
CompileToMethod cannot compile constant 'some value' because it is a non-trivial value, such as a live object. Instead, create an expression tree that can construct this value.
这就是我想要做的:
MethodBuilder evaluateOnCondition = tb.DefineMethod("EvaluateOnCondition", MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new[] { typeof(object), typeof(object) });
onCondition.CompileToMethod(evaluateOnCondition); // throw the error
onCondition 变量是一个 LambdaExpression,是用 Linq 表达式创建的比较条件,表示以下伪代码:obj1.prop1 == obj2.prop1
这是我的 StackTrace:
at System.Linq.Expressions.Compiler.BoundConstants.EmitCacheConstants(LambdaCompiler lc)
at System.Linq.Expressions.Compiler.LambdaCompiler..ctor(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method)
at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, MethodBuilder method, DebugInfoGenerator debugInfoGenerator)
at System.Linq.Expressions.LambdaExpression.CompileToMethodInternal(MethodBuilder method, DebugInfoGenerator debugInfoGenerator)
at System.Linq.Expressions.LambdaExpression.CompileToMethod(MethodBuilder method)
at Integra.Space.Language.Runtime.LanguageTypeBuilder.CreateEqualsMethod(TypeBuilder tb, Type parentType, Type typeOtherSource, Boolean isSecondSource, LambdaExpression onCondition) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\TypeBuilders\LanguageTypeBuilder.cs:line 343
at Integra.Space.Language.Runtime.LanguageTypeBuilder.CreateTypeBuilder(List`1 listOfFields, Type parentType, Boolean overrideGetHashCodeMethod, Boolean overrideEquals, Type typeOtherSource, Boolean isSecondSource, LambdaExpression onCondition) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\TypeBuilders\LanguageTypeBuilder.cs:line 165
at Integra.Space.Language.Runtime.LanguageTypeBuilder.CompileExtractedEventDataComparerTypeForJoin(Type parentType, Type typeOfTheOtherSource, Boolean isSecondSource, LambdaExpression onCondition) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\TypeBuilders\LanguageTypeBuilder.cs:line 92
at Integra.Space.Language.Runtime.ObservableConstructor.CreateProjectionExpression(PlanNode plans) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 3033
at Integra.Space.Language.Runtime.ObservableConstructor.CreateExpressionNode(PlanNode actualNode, Expression leftNode, Expression rightNode) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 358
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 304
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 313
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 299
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 299
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 313
at Integra.Space.Language.Runtime.ObservableConstructor.GenerateExpressionTree(PlanNode plan) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 313
at Integra.Space.Language.Runtime.ObservableConstructor.CreateObservableJoin(PlanNode actualNode) in C:\Users\Oscar\Documents\GitHubVisualStudio\Integra.Space.Language\Integra.Space.Language\Runtime\ObservableConstructor.cs:line 936
onCondition 变量的调试视图
.Block(System.Boolean $variable) {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the equal operation '==': ")
} .Else {
.Default(System.Void)
};
$variable = (System.Object).Block(System.Object $variable) {
.If (.Constant<System.Reflection.RuntimePropertyInfo>(System.Object _adapter_Name) == null) { // 12 line
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_0._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var1) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 162 con t1.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 162, Instruction: t1.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var1)
}
}
};
$variable
} == (System.Object).Block(System.Object $variable) {
.If (.Constant<System.Reflection.RuntimePropertyInfo>(System.Object _adapter_Name) == null) {
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_1._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var2) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 188 con t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 188, Instruction: t2.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var2)
}
}
};
$variable
};
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the equal operation")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var3) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("Error con la expresion de igualdad en la linea: 0 columna: 167 con t1.@event.Adapter.Name == t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 167, Instruction: t1.@event.Adapter.Name == t2.@event.Adapter.Name, Error: RE43: Error with the equal operation '=='",
$var3)
}
};
$variable
}
我怀疑是内核的这一行抛出了错误
顺便说一句:C# 中的 非平凡值 是什么? 我该如何解决这个问题?
如果您需要更多信息,请告诉我
我解决了这个问题,如果您想使用 CompileToMethod 方法将表达式转换为方法的 IL 主体,基本上您不能将反射用于表达式树.现在这是我的 onCondition 调试视图:
.Block(System.Boolean $variable) {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the equal operation '==': ")
} .Else {
.Default(System.Void)
};
$variable = (System.Object).Block(System.Object $variable) {
.If (True == False) { // 12 line
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_0._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var1) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 162 con t1.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 162, Instruction: t1.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var1)
}
}
};
$variable
} == (System.Object).Block(System.Object $variable) {
.If (True == False) {
$variable = .Default(System.Object)
} .Else {
.Try {
.Block() {
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("Start of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
$variable = $NewScopeParameter_1._adapter_Name;
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the get property operation: _adapter_Name")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var2) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("No fue posible obtener la propiedad _adapter_Name, error en la linea: 0 columna: 188 con t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 188, Instruction: t2.@event.Adapter.Name, Error: RE5: Error with the get property operation",
$var2)
}
}
};
$variable
};
.If (
True
) {
.Call System.Diagnostics.Debug.WriteLine("End of the equal operation")
} .Else {
.Default(System.Void)
};
.Default(System.Void)
}
} .Catch (System.Exception $var3) {
.Block() {
.Call System.Diagnostics.Debug.WriteLine("Error con la expresion de igualdad en la linea: 0 columna: 167 con t1.@event.Adapter.Name == t2.@event.Adapter.Name")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 167, Instruction: t1.@event.Adapter.Name == t2.@event.Adapter.Name, Error: RE43: Error with the equal operation '=='",
$var3)
}
};
$variable
}
你可以看到第 12 行我删除了反射的使用以获得 属性 _adapter_Name.
What is non-trivial value in C#? How could I fix this?*
一般null
, bool
, char
, sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, float
, double
, decimal
, string
, Type
, MethodBase
都可以。其他都不是。
从VariableBinder.VisitConstant
开始就可以看到:
if (ILGen.CanEmitConstant(node.Value, node.Type))
{
return node;
}
this._constants.Peek().AddReference(node.Value, node.Type);
转到 AddReference
是不好的,并且会在长时间 运行 中导致您看到的异常。
然后您可以查看 ILGen.CanEmitConstant
并查看已完成的测试。
为什么会这样?因为你正试图在一个方法中编译一个对象。虽然如果您使用 LambdaExpression.Compile()
这通常是可能的,因为对象并没有真正保存在方法中,而只是对内存中对象的引用,如果您使用 CompileToMethod()
. NET 必须能够在方法内保存对象的副本,因为 CompileToMethod()(和 MethodBuilder
/TypeBuilder
/AssemblyBuilder
)能够生成新的 dll。这些 dll 可以在 machines/loaded 天后与其他 machines/loaded 共享(它们是 "normal" dll),因此不能保证它们仅在当前程序的生命周期内是 运行。为此,.NET 需要序列化对象,然后在调用方法时反序列化它。但这不受支持。显然,这不会发生在某些原始类型(我会注意到并非所有 .NET 原始类型都受支持。缺少 IntPtr
和 UIntPtr
)以及一些特殊类型,如 Type
(在 .NET 中有特殊处理)。