传递Lamba表达式列表以访问属性

时间:2017-04-19 23:09:56

标签: c# reflection lambda

我今天有一个静态函数,我传递一个Property表达式并从中创建一个字符串:

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

我想将其更改为处理这样​​的表达式列表:

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

在第二种情况下,我会遍历表达式并执行我正在做的任何逻辑。

这就是我现在调用该函数的方式:

SomeFunction(this, m => m.nameOfProperty)

我如何调用此函数并定义表达式列表?我正在尝试这个,但它不起作用:

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

我遇到编译器错误,无法找到TModel和TProperty。要清楚,这是在另一个文件中调用的。

4 个答案:

答案 0 :(得分:1)

&#34;的TModel&#34;和&#34; TProperty&#34;是通用参数而不是类型。但是如果要调用它,则必须输入任何模型类型和任何属性类型。

例如,这应该有效:

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

-

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

就我而言,我使用了动态属性。有了它,你可以使用不同类型的属性,但仔细考虑!!

答案 1 :(得分:1)

您的通用方法SomeFunctionForList包含泛型类型参数TModelTProperty。在第一种情况下,类型推断能够从方法调用的第一和第二参数推断出这些参数的类型。这就是为什么你可以明确地跳过指定类型参数的原因。

但类型推断仅适用于泛型方法。它不适用于从构造函数参数推断类型参数。这就是为什么你应该明确指定List<T>泛型参数的原因。注意:您应该指定类型名称而不是通用参数。例如。如果TModelYourModel类,并且两个属性都有string类型,则方法调用应如下所示:

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

因此,如果要使用类型推断,则不能使用列表构造函数。您可以使用params指定变量的参数数量(作为数组传递)并具有类型推断的好处:

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

然后方法调用看起来像

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

请注意,属性应具有相同的类型。

答案 2 :(得分:1)

您需要指定类型参数,例如:

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

但是,这只允许您使用所有返回相同类型的属性,在本例中为string。您可以改为使用object

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

答案 3 :(得分:0)

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