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

C# 传递Lamba表达式列表以访问属性,c#,reflection,lambda,C#,Reflection,Lambda,我现在有一个静态函数,我传递一个属性表达式,并从中创建一个字符串: public static string SomeFunction<TModel, TProperty>(TModel model, Expression<Func<TModel, TProperty>> expression){...} 如何调用此函数并定义表达式列表?我正在尝试,但它不起作用: SomeFunctionForList(this, n

我现在有一个静态函数,我传递一个属性表达式,并从中创建一个字符串:

public static string SomeFunction<TModel, TProperty>(TModel model, Expression<Func<TModel, TProperty>> expression){...}
如何调用此函数并定义表达式列表?我正在尝试,但它不起作用:

SomeFunctionForList(this,
                    new List<Expression<Func<TModel, TProperty>>> {
                        { m => m.nameOfProperty1},
                        { m => m.nameOfProperty2} 
});
SomeFunctionForList(此,
新名单{
{m=>m.nameOfProperty1},
{m=>m.nameOfProperty2}
});
我得到一个编译器错误,无法找到TModel和TProperty。需要说明的是,这是在另一个文件中调用的。

公共静态字符串SomeFunction(TModel模型,参数表达式[]表达式)
public static string SomeFunction<TModel, TProperty>(TModel model, params Expression<Func<TModel, TProperty>>[] expressions)
“TModel”和“TProperty”是泛型参数,而不是类型。但如果要调用它,则必须输入任何模型类型和任何属性类型

例如,这应该起作用:

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

SomeFunctionForList(此,新列表{
{m=>m.aStringProperty},
{m=>m.aIntegerProperty}
});

在我的例子中,我使用动态作为属性。有了它,您可以使用不同类型的属性,但要小心使用

您有泛型方法
SomeFunctionForList
,带有泛型类型参数
TModel
TProperty
。在第一种情况下,类型推断能够从方法调用的第一个和第二个参数推断这些参数的类型。这就是为什么可以跳过显式指定类型参数

但是类型推断只适用于泛型方法。它不适用于从构造函数参数推断类型参数。这就是为什么您应该显式指定
List
generic参数的原因。注意:您应该指定类型名称而不是泛型参数。例如,如果
TModel
YourModel
类,并且两个属性都具有
string
类型,那么方法调用应该如下所示:

SomeFunctionForList(this,
           new List<Expression<Func<YourModel, string>>> {
                    { m => m.nameOfProperty1},
                    { m => m.nameOfProperty2} 
           });
然后方法调用将如下所示

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

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

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

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

我应该更清楚一点——我的意思是,当我调用函数时,问题就发生了。在该文件中,它无法识别TModel和tPropertyYou必须展开方法并使用反射来找出泛型参数,以便成功调用它们。如果没有方法源代码,很难猜测错误。但是我认为您应该能够通过反射来实现这一点。这个错误是一个编译错误,调用程序将无法编译,因为找不到TModel和TProperty。显然,因为它们是调用code.public静态对象SomeFunction(TModel模型,params Expression[]expressions)=>expressions.Select(e=>(e.Body as System.Linq.expressions.MemberExpression.Member…)范围之外的泛型;我不确定,但我的意思是“TModel”和“TProperty”不是类型。它们是通用参数。您必须将“TModel”替换为任何模型类型,将“TProperty”替换为任何属性类型。您遇到的问题是
TProperty
对于每个属性都是不同的?是的-基本上,我想发送一个模型和一个lamba表达式列表,并让该方法执行其magicGotcha-在现实生活中,我在方法中的参数之后有几个参数,因此params不是一个理想的选项。有没有办法欺骗编译器跳过类型推断?@Corez您不能使用构造函数-类型推断在这里不起作用。您可以创建工厂,该工厂通过通用方法为您创建列表。元组使用相同的方法-您可以调用工厂方法
Tuple.Create(4,“foo”)
而不是调用
newtuple(4,“foo”)
。您的工厂可以简单为
公共静态列表CreateList(params T[]items)=>items.ToList()和用法将是
SomeFunctionForList(这是Factory.CreateList(m=>m.nameOfProperty1,m=>m.nameOfProperty2))
SomeFunctionForList(this,
           new List<Expression<Func<YourModel, string>>> {
                    { m => m.nameOfProperty1},
                    { m => m.nameOfProperty2} 
           });
public static string SomeFunction<TModel, TProperty>(
    TModel model, params Expression<Func<TModel, TProperty>>[] expressions)
SomeFunctionForList(this,
              m => m.nameOfProperty1,
              m => m.nameOfProperty2
           );
SomeFunctionForList(t,
                new List<Expression<Func<Thing, string>>> {
                    { m => m.StringProperty1},
                    { m => m.StringProperty2}
});
SomeFunctionForList(t,
                new List<Expression<Func<Thing, object>>> {
                    { m => m.StringProperty},
                    { m => m.BoolProperty}
});