Switch without cases (but with default) in System.Linq.Expressions - c#

I have tried to create a switch expression with System.Linq.Expressions:
var value = Expression.Parameter(typeof(int));
var defaultBody = Expression.Constant(0);
var cases1 = new[] { Expression.SwitchCase(Expression.Constant(1), Expression.Constant(1)), };
var cases2 = new SwitchCase[0];
var switch1 = Expression.Switch(value, defaultBody, cases1);
var switch2 = Expression.Switch(value, defaultBody, cases2);
but in the last line I get an ArgumentException:
Non-empty collection required. Parameter name: cases
What is the reason of this exception? May be this a bug in Expression.Switch(…)?
In a C# a switch with "default" part only is correct:
switch(expr) {
default:
return 0;
}//switch
UPD: I have submitted an issue to the CoreFX repo on GitHub

There isn't a complete analogy between C#'s switch and SwitchExpression. In the other direction, consider that you can have:
var value = Expression.Parameter(typeof(int));
var meth = Expression.Lambda<Func<int, string>>(
Expression.Switch(
value,
Expression.Call(value, typeof(object).GetMethod("ToString")),
Expression.SwitchCase(Expression.Constant("Zero"), Expression.Constant(0, typeof(int))),
Expression.SwitchCase(Expression.Constant("One"), Expression.Constant(1, typeof(int)))),
value
).Compile();
Console.WriteLine(meth(0)); // Zero
Console.WriteLine(meth(1)); // One
Console.WriteLine(meth(2)); // 2
Here the SwitchExpression returns a value which is something switch cannot do.
So, just as being able to do something with SwitchExpression does not mean you can do it with a switch, so too there's no reason to assume that being able to do something with a switch means you can do it with a SwitchExpression.
That said, I see no good reason why SwitchExpression was set this way, except perhaps that it simplifies the case where an expression has no cases and no default body. That said, I think this was likely just a matter of the expression being generally intended to have multiple cases, and that was what it was coded to support.
I've submitted a pull-request to .NET Core that would allow such case-less expressions, by producing a SwitchExpression where the default value for the type of switchValue has the same body as the default body. This approach means anything that would be surprised by a SwitchExpression with no cases should still cope, avoiding backwards-compatibility issues. The case of there being no default either is dealt with by creating a noop expression that does nothing, so the only case that now still throws an ArgumentException is if there is no case and no default and the type is explicitly set to something other than void, this case being invalid under the typing rules that must obviously still be kept.
[Update: That approach was rejected, but a later pull-request was accepted, so case-less SwitchExpressions are now allowed by .NET Core, though if and when that is adopted by other versions of .NET is another matter].
In the meantime, or if you use another version of .NET, you're best-off using a helper method like:
public static Expression SwitchOrDefault(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases)
{
if (cases != null)
{
// It's possible that cases is a type that can only be enumerated once.
// so we check for the most obvious condition where that isn't true
// and otherwise create a ReadOnlyCollection. ReadOnlyCollection is
// chosen because it's the most efficient within Switch itself.
if (!(cases is ICollection<SwitchCase>))
cases = new ReadOnlyCollection<SwitchCase>(cases);
if (cases.Any())
return Switch(type, switchValue, defaultBody, comparison, cases);
}
return Expression.Block(
switchValue, // include in case of side-effects.
defaultBody != null ? defaultBody : Expression.Empty() // replace null with a noop expression.
);
}
Overloads like:
public static Expression SwitchOrDefault(Expression switchValue, Expression defaultBody, params SwitchCase[] cases)
{
return SwitchOrDefault(switchValue, defaultBody, null, (IEnumerable<SwitchCase>)cases);
}
And so on can then be added.
This results in a trimmer Expression overall than my pull-request, because it cuts out the switch entirely in the no-cases case and just returns the default body. If you really need to have a SwitchExpression then you could create a similar helper method that follows the same logic as that pull-request does in creating a new SwitchCase and then using that.

Related

How to detect actual type of an expression result? [duplicate]

I have a method that accepts a Expression<Func<T, object>> instance. I want to get at the actual data type being returned by a specific expression instance, rather than object.
I can get it to work for direct property references, so if I pass in the expression x => x.IntegerProperty I can get a Type reference for an integer. This approach requires converting it to a MemberExpression.
However, I can't get it to work for arbitrary expressions. For instance, if the expression is x => x.IntegerProperty.ToString() I want to get a Type reference for a string. I can't compile this to a MemberExpression, and if I just .Compile() it and check the return type I get "object".
How can I look at the specific expression instance and derive the actual return type?
Something like this might do the trick. It probably doesn't cover every possibility, but it's a start.
public static Type GetObjectType<T>(Expression<Func<T, object>> expr)
{
if ((expr.Body.NodeType == ExpressionType.Convert) ||
(expr.Body.NodeType == ExpressionType.ConvertChecked))
{
var unary = expr.Body as UnaryExpression;
if (unary != null)
return unary.Operand.Type;
}
return expr.Body.Type;
}
While not impossible, this is particularly difficult. It would require walking the expression tree and doing some potentially complex logic. For example, what would you want to see if I passed in the following expression?
Func<bool, object> expr = switch => switch ? 1 : "False";
This method could either return an int or a string.
Now, you might be able to make more headway by offloading some of this logic on the compiler. You could change your method parameter from Func<T, object> to Func<T, TReturn> and use typeof(TReturn) within the method to determine what the compiler decided the return type of the expression was.
Of course, in the case of my example, you'll still be working against object. But, your example of x => x.IntegerProperty.ToString() will yield string, which is what you're looking for.
Bit of a cheeky way (and it involves actually invoking the Func), but you can do this:
using System;
class Program
{
static Func<T,object> MakeFunc<T>()
{
return x => 23;
}
static Type GetReturnType<T>(Func<T,object> f)
{
return f(default(T)).GetType();
}
static void Main(string[] args)
{
Type t = GetReturnType(MakeFunc<string>());
Console.WriteLine(t);
}
}
It's not guaranteed to work in all situations, I should add - particularly if the default(T) isn't a valid parameter to the Func. But it's a potential starting point at least.

Why typeof(int).ToString() is not constant?

I'm trying to do this:
const string intType = typeof(int).ToString();
switch (typeof(MyT).ToString())
{
case intType:
{
return "int";
break;
}
...
}
But compiler says:
error CS0133: The expression being assigned to 'intType' must be constant
As I know, typeof operator works at compile-time. So, what's wrong?
As I know, typeof operator works at compile-time.
You don't know that because knowledge has to be true. Where did you get the idea that typeof is executed at compile time? It produces a non-constant object. And then there is no guarantee that ToString doesn't produce a different string every time it runs, so it cannot be treated as a constant either.
So, what's wrong?
You're reasoning from a false belief.
The C# specification clearly describes the conditions that must be met for an expression to be a compile-time constant. Those conditions include the expression not containing any typeof operator or method call.
But there are far bigger problems here. I assume that MyT is a generic type parameter, which means you are attempting to switch on the value of a generic type parameter. That is almost always the wrong thing to do.
What are you really trying to do? What problem are you really trying to solve? Because this code you've shown so far indicates that you're going down an unproductive path to solve whatever the real problem is.
I think, it is quite obvious, what he wants to achieve:
He wants to check for type equality in a switch-case instead of via if-elseif. And to be honest, why not? But how can he achieve this?
First option: Wait for C# 7.0. Yeah, shit like this is possible in the future!
Second option: Use strings. But the case strings need to be constant. So what about the wonderful nameof?
I just tried this "beauty" and it works, so maybe this solves your problem:
switch (typeof(Int32).Name)
{
case nameof(Int32):
Console.WriteLine("It's an Int32!");
break;
case nameof(Double):
Console.WriteLine("It's a Double");
break;
}
The only way to compare type MyT with known types is by checking their Type objects for equality. This can be done as follows:
if (typeof(MyT) == typeof(int)) return "int";
if (typeof(MyT) == typeof(decimal)) return "decimal";
// etc...
You cannot use this approach in a switch because (at the moment) a switch requires that the item being checked is of a simple type:
switch (typeof(T)) // Compile error: "switch expression or case label must be a bool,
// char, string, integral, enum, or corresponding nullable type"
{
case typeof(int): return "int";
case typeof(decimal): return "decimal";
// ...
}
Also, as others already said, checking types in this way almost always means that your approach can be improved by applying different object oriented principles.
E.g. instead of MyMethod<MyT>(MyT item) with type checks for MyT, consider making MyMethod(int item), MyMethod(decimal item) etc.
If you are just trying to get a string describing the type of object, you just need to call .GetType() instead.
For example, the following is a small function that will return the string name of the object type.
static string GetTypeString(object obj)
{
return obj.GetType().FullName;
}
This will return to the full path to the object. In int's case, it will return System.Int32. If you only want the Int32 part, use GetType().Name instead.
Also, you don't need to have a break; in a switch if you have a return;
If you have specific code that needs to be run for some types, or a specific string you want to return, you can use a string on the values returned by the above. For example:
static string GetSimpleType(object obj)
{
var stringRepresentation = GetTypeString(obj);
switch (stringRepresentation)
{
case "System.Int64":
case "System.Int32":
return "int";
default:
return stringRepresentation;
}
}
default is a catch all in switch statements for everything that does not have a case. Think of it like an else.
In the above example, we return the same value for int, Int32, and Int64. Case labels can fall through to other case labels if they are empty.
You can find all the values you need to write a switch for by running a simple script, and hard code the string values since they will always be the same for the same types. If the string is different, then the type is different.
Finally, if you are comparing types, if and if else works better:
static string GetSimpleType(object obj)
{
if (obj.GetType() == typeof(int))
{
return "int";
}
return obj.GetType().ToString();
}

Enum.Parse() vs switch performance

Everything is in the title, I've read this question Enum.Parse() or Switch but there is nothing about performance. My Enum is around 10 members long, I'd like to know which one is faster, switch or Enum.Parse() ?
Nice and fast:
public static class EnumHelpers<TTarget>
{
static EnumHelpers()
{
Dict = Enum.GetNames(typeof(TTarget)).ToDictionary(x => x, x => (TTarget)Enum.Parse(typeof(TTarget), x), StringComparer.OrdinalIgnoreCase);
}
private static readonly Dictionary<string, TTarget> Dict;
public static TTarget Convert(string value)
{
return Dict[value];
}
}
switch is always faster, since parse uses reflection to get the names of the members.. but unless the application is performance critical.. (thousands of executions per second).. using Enum.Parse makes code easier to maintain
I've built a fast "switch" version using expression trees.
public static Func<String, TEnum> GetParseEnumDelegate<TEnum>()
{
var eValue = Expression.Parameter(typeof(String), "value"); // (String value)
var tEnum = typeof(TEnum);
return
Expression.Lambda<Func<String, TEnum>>(
Expression.Block(tEnum,
Expression.Switch(tEnum, eValue,
Expression.Block(tEnum,
Expression.Throw(Expression.New(typeof(Exception).GetConstructor(Type.EmptyTypes))),
Expression.Default(tEnum)
),
null,
Enum.GetValues(tEnum).Cast<Object>().Select(v => Expression.SwitchCase(
Expression.Constant(v),
Expression.Constant(v.ToString())
)).ToArray()
)
), eValue
).Compile();
}
...
var parseEnum = GetParseEnumDelegate<YourEnum>();
YourEnum e = parseEnum("SomeEnumValue");
If you need a non-generic version, you must convert the result of the switch from tEnum to typeof(Object).
public static Func<String, Object> GetParseEnumDelegate(Type tEnum)
{
var eValue = Expression.Parameter(typeof(String), "value"); // (String value)
var tReturn = typeof(Object);
return
Expression.Lambda<Func<String, Object>>(
Expression.Block(tReturn,
Expression.Convert( // We need to box the result (tEnum -> Object)
Expression.Switch(tEnum, eValue,
Expression.Block(tEnum,
Expression.Throw(Expression.New(typeof(Exception).GetConstructor(Type.EmptyTypes))),
Expression.Default(tEnum)
),
null,
Enum.GetValues(tEnum).Cast<Object>().Select(v => Expression.SwitchCase(
Expression.Constant(v),
Expression.Constant(v.ToString())
)).ToArray()
), tReturn
)
), eValue
).Compile();
}
I did several perf tests and this delegate version was almost as fast as the native switch. In my scenario (enum with 10 items) it was 5 times faster than Enum.Parse().
As #CaldasGSM answered, the biggest problem is the reflection that is happening inside the Enum.Parse method. In addition just the number of IF's used in the Enum.Parse internal implementation is much higher than the number of conditions in your switch statement, not to count the other code inside that method. All of that makes it much inferior to a switch.
If you are processing a small number of items like you said than there is actually no significant difference if you are using Enum.Parse vs switch. For a large number of items it is a different story.
However, i would add that one more problem with Enum.Parse is that you have to handle three exception types using try-catch blocks in cases your parsing doesn't work, which will slow down your code as well.
In addition you should also not overlook the cost of boxing the enum values in the object type when using Enum.Parse, which is also a performance penalty.
To resolve the mentioned issues a much better alternative is to use the newer Enum.TryParse API, which will make it simpler to handle errors, and also prevent the boxing to object, since it uses generics.
Here is an example:
Items item;
if (!Enum.TryParse("First", true, out item))
{
// Handle error
}
In isolation, the switch will be faster.
But code rarely executes in isolation. Typically, the user will have entered a value, or you will have loaded it from a disk file. The whole purpose of Enum is to have a symbolic representation of a string value so that you can work with it more easily. It also allows you to validate the data that's entered.
So, let's say you have an enumeration:
public enum Thing
{
Foo,
Bar,
Fooby,
Barby
}
And somebody gives you a string that's supposed to represent one of those. You write a switch statement:
switch (s)
{
case "Foo": break;
case "Bar": break;
case "Fooby": break;
case "Barby": break;
default : throw new ArgumentException();
}
What happens if the user entered "foo"? Are you going to reject it because the case isn't correct? Very unfriendly behavior. So you modify your code to do a ToLower() on the string, and modify your cases to use all lower case.
It's crazy. Your code will be much easier to understand and maintain if you use Enum.TryParse to convert it to an enum, and then do what needs to be done using the enum value.
Use a switch (I prefer using parse anyway because of it's more maintainable).
Anyway, premature optimization is the root of all evil.

Why can't an anonymous method be assigned to var?

I have the following code:
Func<string, bool> comparer = delegate(string value) {
return value != "0";
};
However, the following does not compile:
var comparer = delegate(string value) {
return value != "0";
};
Why can't the compiler figure out it is a Func<string, bool>? It takes one string parameter, and returns a boolean. Instead, it gives me the error:
Cannot assign anonymous method to an
implicitly-typed local variable.
I have one guess and that is if the var version compiled, it would lack consistency if I had the following:
var comparer = delegate(string arg1, string arg2, string arg3, string arg4, string arg5) {
return false;
};
The above wouldn't make sense since Func<> allows only up to 4 arguments (in .NET 3.5, which is what I am using). Perhaps someone could clarify the problem. Thanks.
UPDATE: This answer was written over ten years ago and should be considered to be of historical interest; in C# 10 the compiler will infer some delegate types.
Others have already pointed out that there are infinitely many possible delegate types that you could have meant; what is so special about Func that it deserves to be the default instead of Predicate or Action or any other possibility? And, for lambdas, why is it obvious that the intention is to choose the delegate form, rather than the expression tree form?
But we could say that Func is special, and that the inferred type of a lambda or anonymous method is Func of something. We'd still have all kinds of problems. What types would you like to be inferred for the following cases?
var x1 = (ref int y)=>123;
There is no Func<T> type that takes a ref anything.
var x2 = y=>123;
We don't know the type of the formal parameter, though we do know the return. (Or do we? Is the return int? long? short? byte?)
var x3 = (int y)=>null;
We don't know the return type, but it can't be void. The return type could be any reference type or any nullable value type.
var x4 = (int y)=>{ throw new Exception(); }
Again, we don't know the return type, and this time it can be void.
var x5 = (int y)=> q += y;
Is that intended to be a void-returning statement lambda or something that returns the value that was assigned to q? Both are legal; which should we choose?
Now, you might say, well, just don't support any of those features. Just support "normal" cases where the types can be worked out. That doesn't help. How does that make my life easier? If the feature works sometimes and fails sometimes then I still have to write the code to detect all of those failure situations and give a meaningful error message for each. We still have to specify all that behaviour, document it, write tests for it, and so on. This is a very expensive feature that saves the user maybe half a dozen keystrokes. We have better ways to add value to the language than spending a lot of time writing test cases for a feature that doesn't work half the time and doesn't provide hardly any benefit in cases where it does work.
The situation where it is actually useful is:
var xAnon = (int y)=>new { Y = y };
because there is no "speakable" type for that thing. But we have this problem all the time, and we just use method type inference to deduce the type:
Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });
and now method type inference works out what the func type is.
Only Eric Lippert knows for sure, but I think it's because the signature of the delegate type doesn't uniquely determine the type.
Consider your example:
var comparer = delegate(string value) { return value != "0"; };
Here are two possible inferences for what the var should be:
Predicate<string> comparer = delegate(string value) { return value != "0"; }; // okay
Func<string, bool> comparer = delegate(string value) { return value != "0"; }; // also okay
Which one should the compiler infer? There's no good reason to choose one or the other. And although a Predicate<T> is functionally equivalent to a Func<T, bool>, they are still different types at the level of the .NET type system. The compiler therefore cannot unambiguously resolve the delegate type, and must fail the type inference.
Eric Lippert has an old post about it where he says
And in fact the C# 2.0 specification
calls this out. Method group
expressions and anonymous method
expressions are typeless expressions
in C# 2.0, and lambda expressions join
them in C# 3.0. Therefore it is
illegal for them to appear "naked" on
the right hand side of an implicit
declaration.
Different delegates are considered different types. e.g., Action is different than MethodInvoker, and an instance of Action can't be assigned to a variable of type MethodInvoker.
So, given an anonymous delegate (or lambda) like () => {}, is it an Action or a MethodInvoker? The compiler can't tell.
Similarly, if I declare a delegate type taking a string argument and returning a bool, how would the compiler know you really wanted a Func<string, bool> instead of my delegate type? It can't infer the delegate type.
The following points are from the MSDN regarding Implicitly Typed Local Variables:
var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.
The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement.
It is important to understand that the var keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.
MSDN Reference: Implicitly Typed Local Variables
Considering the following regarding Anonymous Methods:
Anonymous methods enable you to omit the parameter list.
MSDN Reference: Anonymous Methods
I would suspect that since the anonymous method may actually have different method signatures, the compiler is unable to properly infer what the most appropriate type to assign would be.
My post doesn't answer the actual question, but it does answer the underlying question of :
"How do I avoid having to type out some fugly type like Func<string, string, int, CustomInputType, bool, ReturnType>?" [1]
Being the lazy/hacky programmer that I am, I experimented with using Func<dynamic, object> - which takes a single input parameter and returns an object.
For multiple arguments, you can use it like so:
dynamic myParams = new ExpandoObject();
myParams.arg0 = "whatever";
myParams.arg1 = 3;
Func<dynamic, object> y = (dynObj) =>
{
return dynObj.arg0.ToUpper() + (dynObj.arg1 * 45); //screw type casting, amirite?
};
Console.WriteLine(y(myParams));
Tip: You can use Action<dynamic> if you don't need to return an object.
Yeah I know it probably goes against your programming principles, but this makes sense to me and probably some Python coders.
I'm pretty novice at delegates... just wanted to share what I learned.
[1] This assumes that you aren't calling a method that requires a predefined Func as a parameter, in which case, you'll have to type that fugly string :/
Other answers were correct at the time they were written, but starting from C# 10.0 (from 2021), the compiler can infer a suitable delegate type (like some Func<...>, Action<...> or generated delegate type) in such cases.
See C# 10 Features - Lambda improvements.
var comparer = delegate(string value) {
return value != "0";
}; // OK in C# 10.0, picks 'Func<string, bool>' in this case
Of course the more usual syntax is to us =>, so:
var comparer = (string value) => {
return value != "0";
}; // OK in C# 10.0, picks 'Func<string, bool>' in this case
How is about that?
var item = new
{
toolisn = 100,
LangId = "ENG",
toolPath = (Func<int, string, string>) delegate(int toolisn, string LangId)
{
var path = "/Content/Tool_" + toolisn + "_" + LangId + "/story.html";
return File.Exists(Server.MapPath(path)) ? "<a style=\"vertical-align:super\" href=\"" + path + "\" target=\"_blank\">execute example</a> " : "";
}
};
string result = item.toolPath(item.toolisn, item.LangId);

Can I capture a local variable into a LINQ Expression as a constant rather than a closure reference?

I'd like to say
int x = magic(), y = moremagic();
return i => i + (x/y);
and have the x be captured as a constant instead of a variable reference. The idea is that x will never change and so when the expression is later compiled, the compiler to can do constant folding and produce more efficient code -- i.e. calculating x/y once instead of on every call, via pointer dereferences into a closure record.
There is no way to mark x as readonly within a method, and the compiler is not clever enough to detect that it doesn't change after the creation of the expression.
I'd hate to have to build the expression by hand. Any brilliant ideas?
UPDATE: I ended up using the marvelous LinqKit to build a partial evaluator that will do the substitutions I want. The transform is only safe if you know that relevant references will not change, but it worked for my purposes. It is possible to restrict the partial evaluation only to direct members of your closure, which you control, by adding an extra check or two in there, which is fairly obvious on inspection of the sample code provided in the LinqKit.
/// <summary>Walks your expression and eagerly evaluates property/field members and substitutes them with constants.
/// You must be sure this is semantically correct, by ensuring those fields (e.g. references to captured variables in your closure)
/// will never change, but it allows the expression to be compiled more efficiently by turning constant numbers into true constants,
/// which the compiler can fold.</summary>
public class PartiallyEvaluateMemberExpressionsVisitor : ExpressionVisitor
{
protected override Expression VisitMemberAccess(MemberExpression m)
{
Expression exp = this.Visit(m.Expression);
if (exp == null || exp is ConstantExpression) // null=static member
{
object #object = exp == null ? null : ((ConstantExpression)exp).Value;
object value = null; Type type = null;
if (m.Member is FieldInfo)
{
FieldInfo fi = (FieldInfo)m.Member;
value = fi.GetValue(#object);
type = fi.FieldType;
}
else if (m.Member is PropertyInfo)
{
PropertyInfo pi = (PropertyInfo)m.Member;
if (pi.GetIndexParameters().Length != 0)
throw new ArgumentException("cannot eliminate closure references to indexed properties");
value = pi.GetValue(#object, null);
type = pi.PropertyType;
}
return Expression.Constant(value, type);
}
else // otherwise just pass it through
{
return Expression.MakeMemberAccess(exp, m.Member);
}
}
}
No there is no way to do this in C#. The compiler does not support capturing variables by value / const. Nor can you convert a non-const value into a const value at runtime in this manner.
Additionally the C# compiler only does constant folding during the initial compilation for known constant values. If it was possible to freeze a value at runtime into a constant it wouldn't participate in compiler constant folding because it happens at runtime.
The compiler doesn't do this type of "value caching". Constant folding is done at compile time for constants only, not for readonly fields and certainly not for local variables which do not have a known value at compile time.
You have to make this yourself, but it has to stay a closure reference (since the value is in fact not determinable at compile time, which is why it is likely to be put in the closure when the expression is built):
int x = magic(), y = moremagic();
int xy = x/y;
return i => i + xy;
x can't be a constant, because you're doing runtime magic to determine what it is. However, if you know that x and y don't change, try:
int x = magic(), y = moremagic();
int xOverY = x/y;
return i => i + xOverY;
I should also mention that even though the compiled IL code for i => i + (x/y) will show the division, the JIT compiler is almost certainly going to optimize this away.
One technique I used in vb2005 was to use a generic delegate factory to effect by-value closures. I only implemented it for subs rather than functions, but it could be done for functions as well. If extended in that way:
FunctionOf.NewInv()
would be a static function which would accept as parameters a function (described later), a T3, and a T4. The passed-in function should accept parameters of types T2, T3, and T4, and return a T1. The function returned by NewInv would accept one parameter of type T2 and call the passed-in function with that parameter and the ones given to NewInv.
The invocation would look something like:
return FunctionOf.NewInv((i,x,y) => i+x/y, x, y)
If you(like me) are creating some expression builder for SQL queries you may consirer the following: first create a class variable, make it a constant and then access it like this:
var constant= Expression.Constant(values);
var start = Expression.MakeMemberAccess(constant, values.GetMemberInfo(f => f.Start));
var end = Expression.MakeMemberAccess(constant, values.GetMemberInfo(f => f.End));
var more = Expression.GreaterThanOrEqual(memberBody, start);
var less = Expression.LessThanOrEqual(memberBody, end);

Categories

Resources