DelegateDecompiler icon indicating copy to clipboard operation
DelegateDecompiler copied to clipboard

Decompiling throws InvalidOperationException for enums with underlying type other than int

Open gvas opened this issue 8 years ago • 2 comments

.NET Framework 4.5.2 DelegateDecompiler 0.21.0

enum PayGrade : byte
{
    Low,
    High
}

class Employee
{
    public PayGrade PayGrade { get; set; }

    [Computed]
    public decimal Salary
    {
        get
        {
            if (PayGrade == PayGrade.High)
            {
                return 1000M;
            }

            return 10M;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        var employees = new[]
        {
            new Employee { PayGrade = PayGrade.Low },
            new Employee { PayGrade = PayGrade.High },
        }
        .AsQueryable();

        var salaries = (from employee in employees
                        select employee.Salary)
                        .Decompile()
                        .ToList();
    }
}

The code above throws an InvalidOperationException with the following message: "The binary operator Equal is not defined for the types 'System.Byte' and 'System.Int32'."

Changing the PayGrade enum's underlying type to int prevents the exception.

gvas avatar Jan 06 '17 11:01 gvas

any updates for this bug? I have a similar bug when I mixed the enum comparison and other property into one method/property.

[Computed] private static bool B(Order x) { return x.IsActive && (x.OrderStatus >= OrderStatus.Complete|| x.OrderStatus == OrderStatus.Withdraw); }

The exception is: The binary operator GreaterThanOrEqual is not defined for the types 'OrderStatus' and 'System.Int32'.

The ORM is Fluent NHibernate.

qszhuan avatar Jan 28 '18 22:01 qszhuan

I have a workaround, but I'm not sure if it is applicable in your case. Try to add an additional computed property which explicitly casts the enum to int.

[Computed]
public int OrderStatusAsInt
{
    get { return (int)OrderStatus; }
}

[Computed]
public bool B
{
    get { return IsActive && (OrderStatusAsInt >= OrderStatus.Complete || OrderStatusAsInt == OrderStatus.Withdraw); }
}

(I've converted your B method to a property simply because I'm not familiar with computed methods.)

gvas avatar Jan 29 '18 05:01 gvas