Reputation: 354
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
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
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
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
Reputation: 1
public static string SomeFunction<TModel, TProperty>(TModel model, params Expression<Func<TModel, TProperty>>[] expressions)
Upvotes: 0