Corez
Corez

Reputation: 354

Passing a list of Lamba expressions for accessing Properties

I have a static function today that I pass a Property expression and I create a string from it:

public static string SomeFunction<TModel, TProperty>(TModel model, Expression<Func<TModel, TProperty>> expression){...}

I'd like to change it to process a list of expressions like this:

static string SomeFunctionForList<TModel, TProperty>(TModel model, List<Expression<Func<TModel, TProperty>>> expressions){...}

In the second case, I'd loop through the expressions and perform whatever logic I'm doing on them.

This is how I call the function now:

SomeFunction(this, m => m.nameOfProperty)

How would I call this function and define a list of the expressions? I am trying this but it isn't working:

SomeFunctionForList(this,
                    new List<Expression<Func<TModel, TProperty>>> {
                        { m => m.nameOfProperty1},
                        { m => m.nameOfProperty2} 
});

I'm getting a compiler error that TModel and TProperty cannot be found. To be clear, this is called in a different file.

Upvotes: 3

Views: 877

Answers (4)

DavidG
DavidG

Reputation: 118957

You need to specify the type parameters, for example:

SomeFunctionForList(t,
                new List<Expression<Func<Thing, string>>> {
                    { m => m.StringProperty1},
                    { m => m.StringProperty2}
});

However, this only lets you use properties that all return the same type, in this case string. You could use object instead:

SomeFunctionForList(t,
                new List<Expression<Func<Thing, object>>> {
                    { m => m.StringProperty},
                    { m => m.BoolProperty}
});

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236228

You have generic method SomeFunctionForList with generic type parameters TModel and TProperty. In first case type inference is able to infer types of these parameters from first and second arguments of method call. That's why you can skip specifying type arguments explicitly.

But type inference works only for generic methods. It will not work for inference of type parameters from constructor argument. That's why you should specify List<T> generic argument explicitly. Note: you should specify type names instead of generic parameters. E.g. if TModel is YourModel class, and both properties have string type, then method call should look like:

SomeFunctionForList(this,
           new List<Expression<Func<YourModel, string>>> {
                    { m => m.nameOfProperty1},
                    { m => m.nameOfProperty2} 
           });

So, usage of list constructor is not an option here if you want to use type inference. You can use params to specify the variable number of arguments (which are passed as an array) and have benefits of type inference:

public static string SomeFunction<TModel, TProperty>(
    TModel model, params Expression<Func<TModel, TProperty>>[] expressions)

Then method call will look like

SomeFunctionForList(this,
              m => m.nameOfProperty1,
              m => m.nameOfProperty2
           );

Note that properties should have same type.

Upvotes: 2

Sean Stayns
Sean Stayns

Reputation: 4234

"TModel" and "TProperty" are generic parameters and not types. But if you want to call it, you must enter any model type and any property type.

For example, this should work:

private string aStringProperty { get; set; }  
private int aIntegerProperty { get; set; }

-

SomeFunctionForList(this, new List<Expression<Func<Program, dynamic>>>{
                                                              { m => m.aStringProperty},
                                                              { m => m.aIntegerProperty}
                                                          });

In my case, I used a dynamic as property. With that you can use different types of properties, but carefully with that!!

Upvotes: 1

Fernando Miranda
Fernando Miranda

Reputation: 1

public static string SomeFunction<TModel, TProperty>(TModel model, params Expression<Func<TModel, TProperty>>[] expressions)

Upvotes: 0

Related Questions