I have to send expressions over http to my backend. This backend knows about enum Fun
but doesn't have a reference to funs
.
My job is to serialize exp2
in a way the backend can still deserialize it
Is there a way to force passing the enum value rather than a reference to the array element?
var funs = new[] { Fun.Low, Fun.High };
Expression<Func<Funky, bool>> exp1 = x => x.Status == Fun.Low;
Expression<Func<Funky, bool>> exp2 = x => x.Status == funs[0];
Console.WriteLine(exp1);
//Expected: x => (Convert(x.Status, Int32) == 1)
Console.WriteLine(exp2);
//Actual output: x => (Convert(x.Status, Int32) == Convert(value(Program+<>c__DisplayClass0_0).funs[0], Int32))
public enum Fun : int {
Low = 1,
Middle = 2,
High = 420
}
public class Funky {
public Fun Status {get;set;} = Fun.High;
}
Question: how can I make exp2 the same result as exp1?
_____________________________________________
Background Info:
exp1
serializes the enum value as 1
which can be correctly interpreted by the backend.
exp2
serializes funs[0]
as a reference to the actual array-element, looking like this: Convert(value(Program+<>c__DisplayClass0_0).funs[0], Int32)
I also tried exp3
but this outputs the value still as a reference rather than the constant enum value.
What I've tried so far:
//another tests
var afun = new Funky();
var param = Expression.Parameter(typeof(Funky), "x");
var key = afun.GetType().GetProperty("Status");
var lhs = Expression.MakeMemberAccess(param, key);
var rhs = Expression.ArrayIndex(Expression.Constant(funs), Expression.Constant(0));
var body = Expression.Equal(lhs, rhs);
var exp3 = Expression.Lambda<Func<Funky, bool>>(body, param);
Console.WriteLine(exp3);
//x => (x.Status == value(Fun[])[0])
Real-life example:
The Backend holds a database that will be queried via EF-LINQ. The Frontend is supposed to send the exact LINQ Query to the backend.
Lets say a User of the Frontend has a checklist, through which he can toggle which Funky objects he can query from Backend: [x] Low [x] Middle [_] High
-> outputs var funs = new[] { Fun.Low, Fun.Middle };
Now the Frontend will have to put the Expression together like so:
Expression<Func<Funky, bool>> exp2 = x => x.Status == funs[0] || x.Status == funs[1];
and serialize it before it sends it to the backend.
The backend wont be able to understand funs[0]
or funs[1]
. But Backend knows about enum Fun
and could deserialize 1
and 2
correctly.