C# 如何创建表达式<;Func<;t模型,t属性>&燃气轮机;没有TProperty类型显式

C# 如何创建表达式<;Func<;t模型,t属性>&燃气轮机;没有TProperty类型显式,c#,linq,lambda,expression,C#,Linq,Lambda,Expression,中的答案解释了如何创建这样的表达式: var lambda = CreateExpression<SomeModel, bool>("IsAlive"); var lambda=CreateExpression(“IsAlive”); 可以避免显式类型bool,并且该方法从“IsAlive”属性获取返回类型吗 大概是这样的: var lambda = CreateExpression<SomeModel>("IsAlive"); var lambda=CreateE

中的答案解释了如何创建这样的表达式:

var lambda = CreateExpression<SomeModel, bool>("IsAlive");
var lambda=CreateExpression(“IsAlive”);
可以避免显式类型bool,并且该方法从“IsAlive”属性获取返回类型吗

大概是这样的:

var lambda = CreateExpression<SomeModel>("IsAlive");
var lambda=CreateExpression(“IsAlive”);
lambda将是一个
表达式

以及:

var lambda = CreateExpression<SomeModel>("StringProperty");
var lambda=CreateExpression(“StringProperty”);

lambda将是一个
表达式

实际上可以做到这一点,但类型未知。此方法返回的对象将是正确类型的
表达式
,但在编译时不能是强类型的

    static LambdaExpression CreateExpression<TModel>(string propertyName)
    {
        var t = typeof(TModel);
        var param = Expression.Parameter(typeof(TModel), "x");
        //get the type for the 2nd generic arg
        var propType = t.GetProperty(propertyName).PropertyType;
        //make the generic type Func<TModel, TProp>
        Type genericFuncType = typeof(Func<,>).MakeGenericType(new Type[] { typeof(TModel), propType });
        //get the Expression.Lambda method
        MethodInfo mi = typeof(Expression).GetMethods().First(a => a.Name == "Lambda" && a.GetParameters().Length == 2);
        //get the Expression.Lambda<Func<TModel, TProp>> method
        MethodInfo mi2 = mi.MakeGenericMethod(new Type[] { genericFuncType });
        //Call Expression.Lambda<Func<TModel, TProp>>
        return (LambdaExpression)mi2.Invoke(null, new object[] { Expression.PropertyOrField(param, propertyName), new ParameterExpression[] { param }});
    }
静态LambdaExpression CreateExpression(字符串属性名称)
{
var t=类型(TModel);
var param=表达式参数(typeof(TModel),“x”);
//获取第二个泛型参数的类型
var propType=t.GetProperty(propertyName).PropertyType;
//使泛型类型为Func
Type genericFuncType=typeof(Func).MakeGenericType(新类型[]{typeof(TModel),propType});
//获取表达式.Lambda方法
MethodInfo mi=typeof(Expression).GetMethods().First(a=>a.Name==“Lambda”&&a.GetParameters().Length==2);
//获取表达式.Lambda方法
MethodInfo mi2=mi.MakeGenericMethod(新类型[]{genericFuncType});
//调用表达式。Lambda
return(LambdaExpression)mi2.Invoke(null,新对象[]{Expression.PropertyOrField(param,propertyName),新参数Expression[]{param});
}
但是请注意,返回类型现在有些未知,需要使用强制转换(或使用动态)。

所以现在您需要更多的代码来强制转换它。也许这在某种工厂或类似的情况下是有用的-不确定您的用例

class Program
{
    public static void Main(string[] args)
    {
        var theExpression = CreateExpression<Test>("Name");
        var theExpressionStrongType = theExpression as Expression<Func<Test, string>>;
        //now you could use theExpressionStrongType

        //or do this and go wild. :)
        dynamic d = theExpression;


        Console.ReadKey();
    }
}
class Test
{
    public string Name { get; set; }
}
类程序
{
公共静态void Main(字符串[]args)
{
var theExpression=CreateExpression(“名称”);
var theExpressionStrongType=表达式为表达式;
//现在您可以使用ExpressionStrongType
//或者这样做然后发疯。:)
动态d=表达式;
Console.ReadKey();
}
}
课堂测试
{
公共字符串名称{get;set;}
}

免责声明:如果您真的想在生产环境中使用此功能,我会对代码进行大量清理,以便只获取一次引用类型,等等。

出于某种原因,是否要避免显式类型?如果这是因为您希望对不共享任何接口类型的不同模型重用它,那么您可能需要使用dynamic。但是我不太确定它是否会工作,我已经尝试使用dynamic,但不工作。这里确实需要该类型,否则您希望如何使用返回的表达式?@DavidG这正是您遇到的问题。不确定这是一个好方法,但这是一个有趣的学习练习。@TheSoftwareEdi的重点是,这几乎肯定不是一个好方法。你已经发现你现在有一个弱类型的表达式(即
LamdaExpression
而不是
expression)。谢谢!你真的是一个绝地武士。