Какой код C # / Linq копирует все совпадающие значения имени свойства между двумя объектами, не зная их типа? - PullRequest
5 голосов
/ 28 октября 2010

У меня есть хорошо известный класс POCO Customer для возврата из моего метода.Однако я только заполняю свойства, указанные, например, постоянно меняющимся выражением 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 ]

17 голосов
/ 28 октября 2010

Некоторое простое отражение делает свое дело, предполагая, что свойства 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 });
    }
}
6 голосов
/ 28 октября 2010

Вы можете использовать AutoMapper - он создан для этого, я думаю

2 голосов
/ 26 сентября 2013

Адаптация dahlbyk принята ответ , я закончил тем, что использовал следующее в конструкторе, который принял базовый тип и должен был отражать содержимое:

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, где тип this имеет свойство с соответствующим именем, и найдите метод get для типа baseObj, а также set.метод для соответствующего именованного свойства типа this, и если в this доступен метод set, вызовите его, используя метод, возвращенный при вызове метода get для типа baseObj.

Хорошо работает для открытых и закрытых свойств любого (подходящего) типа для обоих типов.

Примечание. Вам потребуется ссылка на System.Linq для функции .Where() в цикле

1 голос
/ 31 января 2016

Не так уж отличается, просто самая компактная и чистая форма, которую я нашел:

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);
  }
}
0 голосов
/ 10 августа 2017
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));
        }
    }
}
0 голосов
/ 26 февраля 2015
    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);
            }

        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...