简体   繁体   English

PropertyInfo 转化为表达式<Func<PropertyType> &gt;

[英]PropertyInfo into Expression<Func<PropertyType>>

I try to make an expression with a PropertyInfo .我尝试用PropertyInfo来表达。 The expression should look like:表达式应如下所示:

Expression < Func < PropertyType >>表达式 < Func < PropertyType >>

I need this Expression for this:我需要这个表达式:
https://github.com/aspnet/AspNetCore/blob/8d46b3a64ea784c95dddeb9d421c7cda6de993a2/src/Components/Web/src/Forms/ValidationMessage.cs https://github.com/aspnet/AspNetCore/blob/8d46b3a64ea784c95dddeb9d421c7cda6de993a2/src/Components/Web/src/Forms/ValidationMessage.cs

The For property needs this kind of Expression. For 属性需要这种表达式。

Can anyone direct me to some links how to get this kind of Expression?任何人都可以将我指向一些如何获得这种表达的链接吗?

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

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

edited;已编辑;

If you need a property accessor for a property name given as string, you must also pass it the the object as parameter.如果您需要为以字符串形式给出的属性名称的属性访问器,您还必须将对象作为参数传递给它。 Therefore you need an因此你需要一个

Expression<Func<Entity, PropertyType>>

This function creates such an expression:此函数创建这样一个表达式:

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);
}

This overload allows you to pass the entity type as generic parameter:此重载允许您将实体类型作为泛型参数传递:

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

This test这个测试

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

prints (assuming OneProperty to be of type int ):打印(假设OnePropertyint类型):

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


You can get an Expression<Func<PropertyType>> if you capture a variable like this:如果您捕获这样的变量,您可以获得一个Expression<Func<PropertyType>>

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

But how do you want to capture a variable if you are constructing an expression dynamically?但是,如果您正在动态构建表达式,您希望如何捕获变量? This is not possible.这不可能。


I found this HtmlHelperValidationExtensions.ValidationMessageFor Method doing what you need:我发现这个HtmlHelperValidationExtensions.ValidationMessageFor 方法做你需要的:

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

You can pass it the Expression<Func<TModel,TResult>> expression from above!您可以从上面传递Expression<Func<TModel,TResult>>表达式! However, you must know the result type in advance.但是,您必须事先知道结果类型。 Otherwise you will have to use reflection to call it.否则你将不得不使用反射来调用它。

I found a solution while trying to bind blazor inputs dynamically:我在尝试动态绑定 blazor 输入时找到了一个解决方案:

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

to get the expression for this statement you should use a constant expression:要获得此语句的表达式,您应该使用常量表达式:

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);

best regards.此致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM