Создайте объект из другого объекта в C #, используя общий код - PullRequest
3 голосов
/ 12 июня 2011

Допустим, у меня есть объект типа User, который выглядит следующим образом:

User {
   Name = "Bob",
   Email = "Bob@gmail.com",
   Class = NULL
}

Может кто-нибудь придумать, как взять этот объект и создать такой объект:

User {
   Name = "Bob",
   Email = "Bob@gmail.com"
}

Использование полностью общего кода?Это означает, что я не хочу жестко кодировать что-либо, имеющее отношение к типу или свойствам, потому что этот код должен быть применен ко всем сущностям на моем сайте.(кстати, тип «Пользователь» - это сущность, поэтому используйте его, если он поможет вам лучше это кодировать).

Я просто пытаюсь найти решение проблемы, которая у меня есть, и я ВЕРЮ, что Заглушки могут решить проблему, но мне нужно сделать это без жесткого кодирования любых типов.или свойства.

Ответы [ 3 ]

5 голосов
/ 12 июня 2011

Используйте отражение, чтобы достичь этого:

public void CopyValues<TSource, TTarget>(TSource source, TTarget target)
{
    var sourceProperties = typeof(TSource).GetProperties().Where(p => p.CanRead);

    foreach (var property in sourceProperties)
    {
        var targetProperty = typeof(TTarget).GetProperty(property.Name);

        if (targetProperty != null && targetProperty.CanWrite && targetProperty.PropertyType.IsAssignableFrom(property.PropertyType))
        {
            var value = property.GetValue(source, null);

            targetProperty.SetValue(target, value, null);
        }
    }
}
4 голосов
/ 12 июня 2011

Дженерики не помогут вам в этом случае.Там может быть какой-то вариант в Entity Framework, но я на самом деле не знаю с этим.

Однако это было бы возможно с помощью Reflection.Вы можете попробовать что-то вроде этого:

public static void CopyProperties(object a, object b)
{
    if (a.GetType() != b.GetType())
        throw new ArgumentException("Types of object a and b should be the same", "b")

    foreach (PropertyInfo property in a.GetType().GetProperties())
    {
        if (!property.CanRead || !property.CanWrite || (property.GetIndexParameters().Length > 0))
            continue;

        property.SetValue(b, property.GetValue(a, null), null);
    }
}

Имейте в виду, что для этого требуется, чтобы все свойства, которые вы хотите скопировать, имели открытый и геттерный методы.Кроме того, существует разница между «глубокой копией» и «мелкой копией», которая означает, что подобъекты также копируются или на них есть только ссылки.Этот пример будет ссылаться только на них, поэтому это будет «мелкая копия»

2 голосов
/ 12 июня 2011

Это похоже на проблему для размышлений, а не на генерики (хотя генерики могут использоваться в качестве скрытого способа кэширования стратегии для размышлений).Если я не прочитал это неправильно, вы захотите создать новый экземпляр и скопировать большинство членов ... Какие размышления хороши, хотя и относительно медленны.Вы можете улучшить скорость с помощью метапрограммирования;при первом запуске (для каждого типа) создайте оптимизированную версию, возможно, с использованием DynamicMethod или Expression, и сохраните типизированный делегат из этого.Тогда просто используйте делегата.

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