如何将PropertyInfo转换为属性表达式并使用它来调用泛型方法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将PropertyInfo转换为属性表达式并使用它来调用泛型方法?相关的知识,希望对你有一定的参考价值。

如何将PropertyInfo转换为属性表达式,可以用来调用StructuralTypeConfiguration<TStructuralType>.Ignore<TProperty>(Expression<Func<TStructuralType, TProperty>> propertyExpression)方法?

我尝试使用Expression.Property()来构造表达式,但当我将此表达式用作propertyExpression参数时,我得到以下错误:

The type arguments for method cannot be inferred from the usage. Try specifying the type arguments explicitly.

这个错误可能是指TProperty类型参数,我不知道如何指定只有PropertyInfo

我这样做是关于:Use Entity Framework's StructuralTypeConfiguration.Ignore() to Ignore all properties but specified set

UPDATE

代码不起作用:

var propertyInfo = typeof(Foo).GetProperties()[0];
var expression = Expression.Default(typeof(Foo));
var expressionProperty = Expression.Property(expression, propertyInfo);
Ignore(expressionProperty);
答案
var entityType = propertyInfo.DeclaringType;
var parameter = Expression.Parameter(entityType, "entity");
var property = Expression.Property(parameter, propertyInfo);
var funcType = typeof(Func<,>).MakeGenericType(entityType, propertyInfo.PropertyType);
var lambda = Expression.Lambda(funcType, property, parameter);

structureConfiguration.GetType()
   .GetMethod("Ignore")
   .MakeGenericMethod(propertyInfo.PropertyType)
   .Invoke(structureConfiguration, new[]{lambda});
另一答案

属性表达式要求属性访问属于特定对象。您可以在这里选择一些选项。首先,如果在一个实体对象中完成此操作,则可以使用ConstantExpression构建属性表达式:

// Already have PropertyInfo in propInfo
Expression.Property(Expression.Constant(this, this.GetType()), propInfo)

但是,既然你需要一个Expression<Func<TStructuralType, TProperty>>,那么你似乎必须使用ParameterExpression构建它:

ParameterExpression pe = Parameter.Expression(typeof(MyEntity), "eParam");
Expression propExp = Expression.Property(pe, propInfo);

但是,这是踢球者...这只是一个会员表达。要转换为您需要的表达式,您需要使用Expression.Lambda来获取所需类型的Func <>表达式。问题?您不知道属性的类型来定义lambda表达式的泛型参数!

Expression<Func<MyEntity, ????>> eFunc = Expression.Lambda<Func<MyEntity, ????>>(propExp, pe);

这是这样做的问题的症结所在。这并不是说它无法完成......只是在这种方式下使用这种方法是行不通的。您将不得不使用一点运行时和静态类型技巧(以及明智地使用Actions而不是Funcs)来使其正常工作。

另一答案

TProperty仅存在于c#源代码文本中。编译器始终将其解析为具体类型。如果你有方法

void Test<T>(T arg)
{
}

并称之为这样

Test("hello");
Test(3);

编译器为两种方法生成代码!

void Test(string arg)
{
}

void Test(int arg)
{
}

这意味着如果要使用可调用方法,则必须为通用参数提供具体类型。

以上是关于如何将PropertyInfo转换为属性表达式并使用它来调用泛型方法?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法从该属性的 getter 中获取 PropertyInfo?

获取元素的值并使其成为 XSLT 中属性的值?

C#遍历类的属性 PropertyInfo.Attributes

VB.net 如何将数据转换为位图(Bitmap)所需要的byte()数组?急!!!!

带有 Mongo 的 OData:System.ArgumentException:'Item' 类型上的属性 'Id' 必须是复杂属性。 (参数'propertyInfo')'

将list转换为datatable