2

Had a hard time finding what I'm trying to do and this post was the closest I could find. This post won't work as I don't know the integer value of the enum, I only know its name. Given the following code:

public enum Foo 
{
    Row = 0,
    Column = 20, // This is why the second post won't work, I only know the name "Column"
    None = 30
}

public static class ExpressionGetter
{
    public static Expression GetExpression(Type type, string name)
    {
        // Not sure what I should do here. I want an expression object for Foo.Row
    }
}

void Main()
{
   var expression = ExpressGetter.GetExpression(typeof(Foo), "Row");
}

Later in my application, I am building expression trees to generate LINQ queries and I know the type of the enum and name of the enum and now I want to create an Expression.Constant of it or if there's another way to do this, I'd like to know how.

I want at the end an expression that looks like this:

Foo.Row

I've tried:

Expression.Property(null, enumType, name)

But it does not work. Results in

ArgumentException: Property 'Row' is not defined for type 'Foo' Parameter name: propertyName

which makes sense because it's a struct not an object.

So I'm not sure how to build the Expression Foo.Row given the enum type Foo and the name as a string.

akousmata
  • 1,005
  • 14
  • 34
  • Are you trying to extract the string value from the enum? Something like, `Print(Foo.Row)` prints out `"Row"`? Or are you trying to get the integer value, like `0, 20, 30`? – CEH Sep 27 '19 at 18:32
  • This question is confusing and I get a feeling that it has a lot of irrelavant information while required info is missing. Do you simply want to get enum value from it's int? – Sach Sep 27 '19 at 18:34
  • 1
    This sounds like an [XY problem](https://meta.stackexchange.com/a/66378/135230). Instead of telling us what you're doing, tell us what your goal is because “create an expression of an enum from its type and name” isn't a goal. – Dour High Arch Sep 27 '19 at 18:36
  • If you're using `null` for the `expression` argument, `MyFoo` has to be a static property, but since you're using `obj.MyFoo` it doesn't appear as though you want to test a static property... – Heretic Monkey Sep 27 '19 at 18:37
  • `Expression.Constant(Foo.Row, typeof(Foo));` – 15ee8f99-57ff-4f92-890c-b56153 Sep 27 '19 at 18:38
  • I won't know the constant at runtime, as my question states, the pieces of information I know are the type of enum and a string of the enum's name. – akousmata Sep 27 '19 at 18:46

2 Answers2

3

An enum value is a static field of the enum type. If you only have the name of the enum value as a string, the second version is what you're looking for. But you could also do Enum.Parse() with the first version.

Expression.Constant(Foo.Row, typeof(Foo));

//  Or any other string that's valid
var name = "Row";
MemberExpression.Field(null, typeof(Foo), name);
0

More or less like this:

public enum EnumerationTest
{
    A, B, C
}

public class ClassTest
{
    public EnumerationTest Test { get; set; }
}

public static Expression PropertyExpression()
{
    // Think of this like a lambda (p) => p.Test == Enumeration.A
    var parameter = Expression.Parameter(typeof(ClassTest), "p"); 
    var property = Expression.PropertyOrField(parameter, "Test");
    var value = (EnumerationTest)Enum.Parse(typeof(EnumerationTest), "A");
    var constant = Expression.Constant(value, typeof(EnumerationTest));

    return Expression.Equal(property, constant);
 }

You generally are using a lot of reflection and string parsing when doing Expression trees. At least that's what I have found in my experience

  • I don't know the enumeration constant at runtime, otherwise, this would be a trivial thing to do, see my edits. – akousmata Sep 27 '19 at 18:45
  • So are you dealing with two properties? Or a property or a variable? Either way, just swap out the Expression.Constant with Expression.PropertyOrField – David Royce Sep 27 '19 at 18:47
  • 1
    You'd assemble the second the same way as I assembled the first one. You have some expression, it has some property of some type. – David Royce Sep 27 '19 at 18:48
  • I apologize, I see the confusion that my question originally caused, but have updated it. `var constant = Expression.Constant(EnumerationTest.A, typeof(EnumerationTest));` is the issue. I don't know that the constant is `EnumerationTest.A`. I know `typeof(EnumerationTest)` and that the name (as a string) of the enumeration value is `A` but that is all. – akousmata Sep 27 '19 at 18:52
  • Thank you for the help, but that is more or less what I had at one point and the result is the expression ends up being only the value (i.e. `Row` instead of `Foo.Row`). Ed Plunkett provided an answer that is working. – akousmata Sep 27 '19 at 19:09
  • The 'Row' value might still work. The expression should know the type. I vaguely remember building expressions that worked that had similar eccentricity. I'm not sure you can go 100% by what shows up in the intellisense. – David Royce Sep 27 '19 at 19:28