C# 转换表达式数组<;Func<;t模型,对象>&燃气轮机;[]到列表的列表<;系统、反射、属性信息>;
是否可以转换C# 转换表达式数组<;Func<;t模型,对象>&燃气轮机;[]到列表的列表<;系统、反射、属性信息>;,c#,reflection,lambda,func,system.reflection,C#,Reflection,Lambda,Func,System.reflection,是否可以转换参数表达式[]includeProperty的数组 是否要列出属性信息的数组 如果是,请解释我如何做 TModel是一个类 编辑: 我执行此操作的目的是,我可以将一个对象的某些属性指定给另一个对象。 我实现这一目标的方法是: public static void Assign(this object destination, object source, List<System.Reflection.PropertyInfo> includeProperties)
参数表达式[]includeProperty的数组
是否要列出属性信息的数组
如果是,请解释我如何做
TModel是一个类
编辑:
我执行此操作的目的是,我可以将一个对象的某些属性指定给另一个对象。
我实现这一目标的方法是:
public static void Assign(this object destination, object source, List<System.Reflection.PropertyInfo> includeProperties)
{
if (destination is IEnumerable && source is IEnumerable)
{
var dest_enumerator = (destination as IEnumerable).GetEnumerator();
var src_enumerator = (source as IEnumerable).GetEnumerator();
while (dest_enumerator.MoveNext() && src_enumerator.MoveNext())
dest_enumerator.Current.Assign(src_enumerator.Current);
}
else
{
//var destProperties = destination.GetType().GetProperties();
foreach (var sourceProperty in source.GetType().GetProperties())
{
foreach (PropertyInfo destProperty in includeProperties)
{
if (destProperty.Name == sourceProperty.Name && destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
{
destProperty.SetValue(destination, sourceProperty.GetValue(source, new object[] { }), new object[] { });
break;
}
}
}
}
}
public static void Assign(此对象目标、对象源、列表includeProperties)
{
if(目标为IEnumerable&&源为IEnumerable)
{
var dest_枚举器=(目标为IEnumerable).GetEnumerator();
var srcu枚举器=(源为IEnumerable).GetEnumerator();
while(dest_enumerator.MoveNext()&&src_enumerator.MoveNext())
dest_enumerator.Current.Assign(src_enumerator.Current);
}
其他的
{
//var destProperties=destination.GetType().GetProperties();
foreach(source.GetType().GetProperties()中的var sourceProperty)
{
foreach(属性InFo destProperty in includeProperties)
{
if(destProperty.Name==sourceProperty.Name&&destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
{
destProperty.SetValue(目标,sourceProperty.GetValue(源,新对象[]{}),新对象[]{});
打破
}
}
}
}
}
另一种方法:
public virtual void Update(object viewModel, params Expression<Func<TModel, object>>[] includeProperties)
{
List<PropertyInfo> pList = new List<PropertyInfo>();
foreach (var prop in includeProperties)
{
//Todo: I should convert prop to PropertyInfo and then add to pList
}
using (new EFUnitOfWorkFactory().Create())
{
TModel model = new TModel();
model.Assign(viewModel, pList);
RepositoryContainer<TRepository>().Update(model);
}
}
公共虚拟无效更新(对象视图模型,参数表达式[]includeProperties)
{
List pList=新列表();
foreach(includeProperties中的var属性)
{
//Todo:我应该将prop转换为PropertyInfo,然后添加到pList
}
使用(新的EFUnitOfWorkFactory().Create())
{
TModel model=新TModel();
model.Assign(viewModel,pList);
RepositoryContainer().Update(模型);
}
}
我将其分为两部分:
第1部分:从表达式中提取属性info
:
公共静态类ExpressionUtil
{
公共静态属性info属性(表达式expr)
{
var member=ExpressionUtil.member(expr);
var prop=作为PropertyInfo的成员;
if(prop==null)
{
抛出新的InvalidOperationException(“指定的成员不是属性”);
}
返回道具;
}
公共静态MemberInfo成员(表达式表达式)
{
//这是一个棘手的情况,因为“object”返回类型。
//以值类型属性为目标的表达式将
//具有一元表达式体,而表达式
//目标引用类型属性将具有MemberExpression
//(或者更具体地说,PropertyExpression)主体。
var unaryExpr=expr.Body作为UnaryExpression;
变量memberExpr=(MemberExpression)(unaryExpr==null?expr.Body:unaryExpr.Operator);
返回成员Expr.Member;
}
}
第2部分:执行投影以获取列表
:
//includeProperty是表达式[]。
列表pList=includeProperties
.Select(ExpressionUtil.Property)
.ToList();
。。。或者(将其插入现有代码中):
List pList=new List();
foreach(includeProperties中的var属性)
{
PropertyInfo pi=ExpressionUtil.Property(prop);
pList.Add(pi);
}
编辑
好了,现在我们知道数组实际上包含了不同表达式树的混合(那些以值类型属性为目标的表达式树,以及那些以引用类型属性为目标的表达式树)。以下将处理这两个问题:
List<PropertyInfo> pList = new List<PropertyInfo>();
foreach (var prop in includeProperties)
{
MemberExpression memberExpr = prop.Body as MemberExpression;
if (memberExpr == null)
{
UnaryExpression unaryExpr = (UnaryExpression)prop.Body;
memberExpr = (MemberExpression)unaryExpr.Operand;
}
PropertyInfo pi = (PropertyInfo)memberExpr.Member;
pList.Add(pi);
}
List pList=new List();
foreach(includeProperties中的var属性)
{
MemberExpression memberExpr=prop.Body作为MemberExpression;
if(memberExpr==null)
{
一元表达式一元表达式=(一元表达式)prop.Body;
memberExpr=(MemberExpression)unaryExpr.Operator;
}
PropertyInfo pi=(PropertyInfo)memberExpr.Member;
pList.Add(pi);
}
我已经调整了ExpressionUtil.Member
,以便在您的情况下以及我最初编写它的一般情况下正常工作
最后一句话
现在,我已经说明了如何使用BCL使事情顺利进行,我想指出的是,映射实体的问题无处不在,有许多专门的第三方工具可以很好地解决这个问题,即AutoMapper().我不明白:您希望如何从Func
检索属性?函数是否返回属性值?我在成员(表达式expr)附加信息中遇到异常:无法将类型为“System.Linq.Expressions.PropertyExpression”的对象强制转换为类型为“System.Linq.Expressions.UnaryExpression”。我的一个参数是m=>m.Title,Title是字符串。非常感谢您的尝试,但仍然存在问题。如果我的参数为m=>m.Id或m=>m.IsActive,那么Id为int,IsActive为bool,我将面临一个异常。。。。。其他信息:无法将类型为“System.Linq.Expressions.UnaryExpression”的对象强制转换为类型为“System.Linq.Expressions.MemberExpression”。@Jahan,请查看我的最新编辑(我已在编辑部分更改了ExpressionUtil.Member
和普通示例,以处理一元表达式和非一元表达式)。就目前情况而言,上面的所有代码示例都应该适合您。如果他们不知道,请让我知道,我会进一步调查。顺便说一句,我完全误诊了UnaryExpression
vsMemberExpression
问题,最初将其归咎于(相当错误)代表差异,而事实上这不可能是问题所在(// includeProperties is Expression<Func<TModel, object>>[].
List<PropertyInfo> pList = includeProperties
.Select(ExpressionUtil.Property)
.ToList();
List<PropertyInfo> pList = new List<PropertyInfo>();
foreach (var prop in includeProperties)
{
PropertyInfo pi = ExpressionUtil.Property(prop);
pList.Add(pi);
}
List<PropertyInfo> pList = new List<PropertyInfo>();
foreach (var prop in includeProperties)
{
MemberExpression memberExpr = prop.Body as MemberExpression;
if (memberExpr == null)
{
UnaryExpression unaryExpr = (UnaryExpression)prop.Body;
memberExpr = (MemberExpression)unaryExpr.Operand;
}
PropertyInfo pi = (PropertyInfo)memberExpr.Member;
pList.Add(pi);
}