Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a list of properties to a method using lambda expressions

Let's say I have a method, which prints the names and values of some properties of an object:

public void PrintProperties(object o, params string[] propertyNames)
{
    foreach (var propertyName in propertyNames)
    {
        // get the property info,
        // then get the property's value,
        // print property-name and -value
    }
}
// method can be used like this
PrintProperties(user, "FirstName", "LastName", "Email");

Now instead of having to pass a list of strings to the method, I'd like to change that method so that the properties can be specified using lambda expressions (not sure if that's the correct term).

E.g. I'd like to be able to call my method (somehow) like this:

PrintProperties(user, u->u.FirstName, u->u.LastName, u->u.Email);

The goal is, to give the user of the method intellisense support, to prevent typing errors. (Similar to the ASP.NET MVC helper methods, like TextBoxFor(u=>u.Name)).

How do I have to define my method, and how can I then get the PropertyInfos inside the method?

like image 336
M4N Avatar asked May 02 '13 15:05

M4N


2 Answers

Use a declaration like this:

void PrintProperties<T>(T obj,
                        params Expression<Func<T, object>>[] propertySelectors)
{
   ...
}

Callable like:

PrintProperties(user, u => u.FirstName, u => u.LastName, u => u.Email);

As for getting property-names out from each lambda, see Retrieving Property name from lambda expression. Do note that you have may have to go a little bit deeper than what is provided in that answer in case the property is a value-type like int (in this case, the compiler will generate a unary Convert expression over the member-access that you want, in order to box the struct).

like image 154
Ani Avatar answered Oct 09 '22 12:10

Ani


Reflection allows you to access fields, properties, events, etc.

public void PrintProperties(object o, params string[] propertyNames)
{
    foreach (var propertyName in propertyNames)
    {
        // Dont have VS now, but it's something like that
        Console.WriteLine(o.GetType().GetProperty(propertyName).GetValue(o, null));
    }
}

I don't have VS now, so it might not even compile, but along these names you can get along with auto-completion...

like image 26
SimpleVar Avatar answered Oct 09 '22 13:10

SimpleVar