PropertyInfo转换为Expression <Func <PropertyType >>

时间:2019-08-06 14:27:40

标签: c#

我尝试使用PropertyInfo进行表达式。表达式应如下所示:

  

表达式>

我需要以下表达式:
https://github.com/aspnet/AspNetCore/blob/8d46b3a64ea784c95dddeb9d421c7cda6de993a2/src/Components/Web/src/Forms/ValidationMessage.cs

For属性需要这种表达式。

任何人都可以将我定向到某些链接以获取这种表达方式吗?

var entity = new Entity;  
var propertyInfo = entity.GetType().GetProperty("OneProperty");

var expr = GetExpression(propertyInfo);
// could be:
// Expression<Func<string>> or Expression<Func<int>>

已编辑;

2 个答案:

答案 0 :(得分:1)

如果您需要一个属性访问器来获取以字符串形式给出的属性名称,则还必须将对象作为参数传递给它。因此,您需要一个

Expression<Func<Entity, PropertyType>>

此函数创建这样的表达式:

private static LambdaExpression CreatePropertyGetterExpression(Type entityType,
                                                               string propertyName)
{
    PropertyInfo property = entityType.GetProperty(propertyName);
    var parameter = Expression.Parameter(entityType, "e");
    var body = Expression.MakeMemberAccess(parameter, property);
    return Expression.Lambda(body, parameter);
}

此重载使您可以将实体类型作为通用参数传递:

private static LambdaExpression CreatePropertyGetterExpression<TEntity>(string propertyName)
{
    return CreatePropertyGetterExpression(typeof(TEntity), propertyName);
}

该测试

var expr = CreatePropertyGetterExpression<Entity>("OneProperty");
Console.WriteLine(expr);
Console.WriteLine(expr.GetType());

打印(假设OnePropertyint类型):

  

e => e.OneProperty
  System.Linq.Expressions.Expression`1 [System.Func`2 [MyProject.Entity,System.Int32]]


如果捕获到这样的变量,则可以获得Expression<Func<PropertyType>>

Entity e = new Entity { PropertyOne = 42 };
Expression<Func<int>> expr = () => e.PropertyOne;

但是,如果要动态构造一个表达式,该如何捕获变量?这是不可能的。


我发现这HtmlHelperValidationExtensions.ValidationMessageFor Method可以满足您的需求:

public static IHtmlContent ValidationMessageFor<TModel,TResult> (
    this IHtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel,TResult>> expression,
    string message,
    object htmlAttributes);

您可以从上方传递Expression<Func<TModel,TResult>>表达式!但是,您必须事先知道结果类型。否则,您将不得不使用反射来调用它。

答案 1 :(得分:0)

我试图动态绑定blazor输入时找到了一个解决方案:

Entity e = new Entity { PropertyOne = 42 };
Expression<Func<int>> expr = () => e.PropertyOne;

要获取此语句的表达式,您应该使用常量表达式:

var e = new Entity() { PropertyOne = 42 };
var property = typeof(Entity).GetProperty("PropertyOne");
var entityType = typeof(Entity);
var parameter = Expression.Constant(e);
var body = Expression.MakeMemberAccess(parameter, property);

var resultToReturn = Expression.Lambda<func<TValue>>(body);

最诚挚的问候。