简体   繁体   中英

How to debug Expression.Lambda? (Difference in Expressions tree evaluation between .net core 2.1 and .net core 3.1)

I've created a small program that shows some differences between .net core 2.1 and 3.1:

using System;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Query;

public class Program
{
    public static void Main()
    {
        var entityObject = Expression.Parameter(typeof(object), "objParam");
        var cev = new ExpressionPrinter();
        var entObjPrint = cev.PrintDebug(entityObject);
        Console.WriteLine(entObjPrint);
    }
}

the print out in 2.1: Unhandled parameter: objParam

the print out in 3.1: (Unhandled parameter: objParam){0}

notice the brackets and the extra {0} at the end. Can someone explain to me why is this difference?

NOTE: This is a shortened version of my issue, but also when I try to compile an Expression.Lambda in .net core 3.1 I get an error (not exception) which is not present in the .net core 2.1 version of my code:

{Method = <Internal Error evaluating expression>}

UPDATE : It seems that the PrintDebug implementation have changed. If you call PrintDebug(enitytObject,null,false) there will no longer be {0}.

With that in mind, maybe the issue is not that, but still I do not know how to debug a compile error of an lambda expression (not to be mistaken with linq lambda).

More on the issue This is part of the code where I am getting the error:

//return all fields/properties that have an attribute indicating they need to be localized
var locFields = EntityLocalizationReflection.GetLocalizationFields(entityType);
            if (locFields?.Count > 0)
            {
                var updater = new EntityLocalizerUpdater();
                // create a parameter representing an object (object)
                var entityObject = Expression.Parameter(typeof(object), "objParam");
                // convert the parameter to an IEntityType ((object)Category)
                var entityInstance = Expression.Convert(entityObject, entityType.Metadata.ClrType);
                // iterate over all fields/properties that needs to be localized
                foreach (var loc in locFields)
                {
                    // Depending if the localized element is a field or a property, create the expression
                    var target = loc.Item2.MemberType == MemberTypes.Property
                        ? Expression.Property(entityInstance, (PropertyInfo)loc.Item2)
                        : Expression.Field(entityInstance, (FieldInfo)loc.Item2);

                    var getter = Expression.Lambda<Func<object, EntityLocalizer>>(target, entityObject);false);
//getter.Compile() failes only in .NET code 3.1
                    updater.Add(getter.Compile(), loc.Item1.EntityName);
                }

                //...some other code..//
            }

UPDATE 2 : Thanks to @MarcGravell there is a minimum runnable code here: https://gist.github.com/mgravell/57d5691741e1379f32c2d22540acf8da and the error can be viewed if a "Quick Watch" is performed over getter.Compile() or assign some variable to it ( var compiled = getter.Compile(); ) and then inspect it during Debug.

It seems that it is a debugger issue when showing Expressions in .net core 3.1. An issue has been open.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM