gpt4 book ai didi

c# - CompileToMethod 无法编译常量 '',因为它是一个不平凡的值,例如事件对象

转载 作者:行者123 更新时间:2023-12-04 15:26:01 25 4
gpt4 key购买 nike

我正在尝试使用名为 EvaluateOnCondition 的方法创建带有 Reflection.Emit 的类型。我使用 Linq Expressions 生成方法的主体,并且我想使用 CompileToMethod 将表达式的 IL 注入(inject)到 EvaluateOnConditionLambdaExpression 的 Strong> 方法,但是当我执行 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 变量的调试 View

.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 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0571342b456073606b712b446164757160772b4b646860" rel="noreferrer noopener nofollow">[email protected]</a>")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 162, Instruction: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5c286d721c392a393228721d383d2c28392e72123d3139" rel="noreferrer noopener nofollow">[email protected]</a>, 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 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9febadb1dffae9faf1ebb1defbfeefebfaedb1d1fef2fa" rel="noreferrer noopener nofollow">[email protected]</a>")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 188, Instruction: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0d793f234d687b686379234c696c7d79687f23436c6068" rel="noreferrer noopener nofollow">[email protected]</a>, 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 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1c682d325c796a797268325d787d6c68796e32527d7179" rel="noreferrer noopener nofollow">[email protected]</a> == <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="80f4b2aec0e5f6e5eef4aec1e4e1f0f4e5f2aecee1ede5" rel="noreferrer noopener nofollow">[email protected]</a>")
;
.Throw .New Integra.Space.Language.Exceptions.RuntimeException(
"RuntimeException: Line: 0, Column: 167, Instruction: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2155100f614457444f550f604540515544530f6f404c44" rel="noreferrer noopener nofollow">[email protected]</a> == <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6317514d230615060d174d220702131706114d2d020e06" rel="noreferrer noopener nofollow">[email protected]</a>, Error: RE43: Error with the equal operation '=='",
$var3)
}
};
$variable
}

我怀疑错误是在核心的这一行抛出的。

BoundConstants line 133

顺便说一句:C# 中的非平凡值(value)是什么?我该如何解决这个问题?

请告诉我您是否需要更多信息

最佳答案

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 可以与其他计算机共享/几天后加载(它们是“正常”dll),因此不能保证它们仅在当前程序的生命周期内运行。为此,.NET 需要序列化对象,然后在调用方法时反序列化它。但这不受支持。显然,某些基元类型不会发生这种情况(我会注意到,并非所有 .NET 基元类型都受支持。缺少 IntPtrUIntPtr )以及某些特殊类型,如 Type 。 (在 .NET 中有特殊处理)。

关于c# - CompileToMethod 无法编译常量 '<some value>',因为它是一个不平凡的值,例如事件对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35903724/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com