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
vs
MemberExpression
问题,最初将其归咎于(相当错误)代表差异,而事实上这不可能是问题所在(// 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);
}