代码之家  ›  专栏  ›  技术社区  ›  Zachary Scott

什么c/linq代码复制两个对象之间所有匹配的属性名值,而不知道它们的类型?

  •  5
  • Zachary Scott  · 技术社区  · 14 年前

    我有一个著名的客户POCO类要从我的方法返回。但是,我只填充由不断变化的表达式p=>new p.id,p.name指定的属性,例如,作为方法的参数。

    不知怎么的,我需要复制这两个对象之间所有匹配的字段。

    var returnObject = IList<Customer>();
    var partialFieldObject = DC.Customers.Select( expParameter); // wont know the fields
    
    foreach( var partialRecord in partialFieldObject)
    {    foreach (var property in partialRecord // Pseudo code)
         {
             returnObject[property] = property.value; // More Pseudo code
         }
    }
    End result is a strongly typed Customer POCO returned that only has the selected fields populated with values.
    
    6 回复  |  直到 7 年前
        1
  •  17
  •   dahlbyk    14 年前

    假设属性 partialFieldObject 与上的属性完全对齐(区分大小写) Customer

    void SetProperties(object source, object target)
    {
        var customerType = target.GetType();
        foreach (var prop in source.GetType().GetProperties())
        {
            var propGetter = prop.GetGetMethod();
            var propSetter = customerType.GetProperty(prop.Name).GetSetMethod();
            var valueToSet = propGetter.Invoke(source, null);
            propSetter.Invoke(target, new[] { valueToSet });
        }
    }
    
        2
  •  6
  •   Preet Sangha    14 年前

    你可以用 AutoMapper -我想它是用来做这些事情的

        3
  •  2
  •   Community CDub    7 年前

    适应 dahlbyk 已接受 answer ,我在接受基类型并需要镜像内容的构造函数中使用了以下内容:

    var thisType = this.GetType();
    foreach (var prop in baseObj.GetType().GetProperties()
        .Where(p => thisType.GetProperty(p.Name) != null))
    {
        var propGetter = prop.GetGetMethod();
        var propSetter = thisType.GetProperty(prop.Name).GetSetMethod();
        if (propSetter != null)
            propSetter.Invoke(this, new[] { propGetter.Invoke(baseObj, null) });
    }
    

    基本上,在 baseObj 键入Where this 类型具有具有匹配名称的属性,并找到 get 方法 基对象 类型以及 set 上匹配的命名属性的方法 类型,如果有 设置 方法可用于 ,使用从调用 得到 方法 基对象 类型。

    适用于两种类型上任何(匹配)类型的公共和私有属性。

    注意:您需要参考 System.Linq 对于 .Where() 循环中的func

        4
  •  1
  •   Gábor    7 年前

    没有什么不同,只是我发现的最紧凑和最干净的形式:

    void CopyProperties(object src, object dest) {
      foreach (var source in src.GetType().GetProperties().Where(p => p.CanRead)) {
        var prop = dest.GetType().GetProperty(source.Name);
        if (prop?.CanWrite == true)
          prop.SetValue(dest, source.GetValue(src, null), null);
      }
    }
    
        5
  •  0
  •   Yargicx    10 年前
        public static void CopyPropertiesTo<T, TU>(this T source, TU dest)
        {
    
            var sourceProps = typeof (T).GetProperties().Where(x => x.CanRead).ToList();
            var destProps = typeof(TU).GetProperties()
                    .Where(x => x.CanWrite)
                    .ToList();
    
            foreach (var sourceProp in sourceProps)
            {
                if (destProps.Any(x => x.Name == sourceProp.Name))
                {
                    var p = destProps.First(x => x.Name == sourceProp.Name);
                    p.SetValue(dest, sourceProp.GetValue(source, null), null);
                }
    
            }
    
        }
    
        6
  •  0
  •   Tnqiang Ren    7 年前
    void Copy(object copyToObject, object copyFromObject)
    {
        BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
    
        FieldInfo[] fields = copyFromObject.GetType().GetFields(flags);
        for (int i = 0; i < fields.Length; ++i)
        {
            FieldInfo fromField = copyFromObject.GetType().GetField(fields[i].Name, flags);
            FieldInfo toField = copyToObject.GetType().GetField(fields[i].Name, flags);
            if(fromField != null)
            {
                toField.SetValue(copyToObject, fromField.GetValue(copyFromObject));
            }
        }
    }