-3

I have following class (some part is copied from here):

class TestExpression
{
    public string GetValue(Expression<Func<object>> field)
    {
        string str = GetColumnName(field);
        //Do something with 'str'
        return str;//Return modified 'str'
    }

    public string GetColumnName<TType>(Expression<Func<TType>> field)
    {
        var me = field.Body as MemberExpression;
        if(me == null)
        {
            throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
        }
        return me.Member.Name;
    }
}

public sealed class MyClass
{
    public static int StaticProperty { get; set; }
    public int InstanceProperty { get; set; }
}

Following is the way I use above class:

TestExpression te = new TestExpression();
string name;
name = te.GetColumnName(() => MyClass.StaticProperty);//Works correctly
name = te.GetColumnName(() => new MyClass().InstanceProperty);//Works correctly

name = te.GetValue(() => MyClass.StaticProperty);//Fail
name = te.GetValue(() => new MyClass().InstanceProperty);//Fail

So, if I call the GetColumnName() function directly, it works all great. But, I need to use this logic at multiple locations, that is why I put it in separate function and call from other functions (like GetValue()). In that case, it does not work. In that case, field.Body as MemberExpression evaluates to null.

I do not want to expose GetColumnName() as public; it will be private function.

How to pass lambda from one function to other function as parameter?

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141

2 Answers2

4

The problem is that your C# code actually includes a type-cast, which you don't see because in the C#, but does happen on the Expression since the expected type is Expression<Func<object>> (note the object!).

() => MyClass.StaticProperty

is actually:

() => (object)MyClass.StaticProperty

The (object) part converts to Convert(MyClass.StaticProperty). The suddenly this isn't a MemberExpression any more, it is a UnaryExpression.

You can prevent all this by making the method generic, thus avoiding the required cast to object:

public string GetValue<TType>(Expression<Func<TType>> field)
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
1

Change the signature of the GetValue method to:

public string GetValue<T>(Expression<Func<T>> field)

Otherwise you are operating on the object where your properties are not visible.