Как бы вы улучшили этот класс поверхностного копирования?

StackOverflow https://stackoverflow.com/questions/469982

  •  19-08-2019
  •  | 
  •  

Вопрос

Я написал класс с одним статическим методом, который копирует значения свойств из одного объекта в другой.Неважно, какого типа каждый объект, важно только то, что они имеют одинаковые свойства.Он делает то, что мне нужно, поэтому я не буду его разрабатывать дальше, но какие улучшения вы бы сделали?

Вот код:

public class ShallowCopy
{
    public static void Copy<From, To>(From from, To to)
        where To : class
        where From : class
    {
        Type toType = to.GetType();
        foreach (var propertyInfo in from.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance))
        {
            toType.GetProperty(propertyInfo.Name).SetValue(to, propertyInfo.GetValue(from, null), null);
        }
    }
}

Я использую его следующим образом:

EmployeeDTO dto = GetEmployeeDTO();
Employee employee = new Employee();
ShallowCopy.Copy(dto, employee);
Это было полезно?

Решение

Ваши DTO сериализуются? Я ожидаю, что в таком случае:

MemberInfo[] sm = FormatterServices.GetSerializableMembers(typeof(From));
object[] data = FormatterServices.GetObjectData(from, sm);
FormatterServices.PopulateObjectMembers(to, sm, data);

Но учтите, что я не совсем согласен с таким общим подходом. Я бы предпочел сильный контракт на копирование ваших DTO, который реализует каждый DTO.

Другие советы

  • Измените имена параметров типа, чтобы они соответствовали соглашениям об именах, например.TFrom и TTo или TSource и TDest (или TDestination).

  • Выполняйте большую часть своей работы с использованием универсального типа, а не просто универсального метода.Это позволяет кэшировать свойства, а также позволяет выводить тип.Вывод типа важен для параметра «TFrom», поскольку он позволяет использовать анонимные типы.

  • Потенциально вы могли бы сделать это невероятно быстро, динамически генерируя код для копирования свойства и сохраняя его в делегате, допустимом для типа «from».Или потенциально сгенерировать его для каждой пары «от/в», что будет означать, что при фактическом копировании вообще не потребуется использовать отражение!(Подготовка кода потребует разового выполнения каждой пары типов, но, будем надеяться, у вас не будет слишком много пар.)

Новый метод, который создал новый экземпляр To и вызвал метод Copy() перед возвратом, может быть полезным.

Вот так:

public static To Create<From, To>(From from)
    where To : class, new()
    where From : class
{
    var to = new To();
    Copy(from, to);
    return to;
}

Решите, что вы хотите сделать, если переданы объекты типов, которые имеют некоторые свойства, но не все. Проверьте наличие свойства в объекте From объекта To, прежде чем пытаться установить его значение. Сделайте & Правильную вещь & Quot; когда вы приходите к собственности, которой не существует. Если все общедоступные свойства должны быть идентичны, вам необходимо проверить, все ли они установлены для объекта <=>, и обработать случай, когда вы этого не сделали соответствующим образом.

Я бы также предположил, что вы можете использовать атрибуты для украшения свойств, которые необходимо скопировать, и игнорировать другие. Это позволит вам легче перемещаться между двумя различными объектами и продолжать поддерживать некоторые общедоступные свойства, которые создаются, а не хранятся в вашем бизнес-объекте.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top