Создание объекта из другого объекта - PullRequest
1 голос
/ 15 декабря 2009

Простите за тупой новый вопрос, но ... Я перемещаю данные из одной таблицы в другую. Схема таблицы назначения идентична исходной таблице, за исключением того, что она имеет несколько дополнительных столбцов. Linq to SQL генерирует классы для представления каждой из этих таблиц. Если у меня есть исходный объект, как мне создать целевой объект из него? Например, исходный объект обладает свойствами A, B, C. Целевой объект имеет A, B, C, X, Y. Я хочу сделать что-то вроде:

  Destination dest = new Destination(Source source, int x, int y)
  {
    this.X = x;
    this.Y = y;
    ...
    // somehow set all the destination properties to 
    // their corresponding source value
  }

Есть ли изящный способ сделать это, кроме настройки простоты каждого из свойств? Могу ли я сделать так, чтобы Destination наследовал от Source? Это поможет?

Ответы [ 3 ]

2 голосов
/ 15 декабря 2009

Почему вы не можете написать свое собственное автоматическое преобразование, используя Reflection? Вы можете сделать что-нибудь под мелодию

   class Program {
     static void Main(string[] args)
     {
       Source item1 = new Source(2, 3, 4);
       Destination item2 = new Destination(item1, ContinueCopy);

       Console.WriteLine(string.Format("X: {0}\n Y: {1}", item2.X, item2.Y));
       Console.ReadKey();
     }

     public static bool ContinueCopy(string name, Type type)
     {
        if (name == "X" && type == typeof(int)) return false;

        return true;
     }
  }

  public class Source {
     public Source() { }
     public Source(int x, int y, int z)
     {
       myX = x;
       myY = y;
       myZ = z;
     }
     private int myX;
     public int X
     {
       get { return myX; }
       set { myX = value; }
     }

     private int myY;
     public int Y
     {
       get { return myY; }
       set { myY = value; }
     }

     private int myZ;
     public int Z
     {
       get { return myZ; }
       set { myZ = value; }
     }
  }


  public class Destination {
     public delegate bool ContinueCopyCallback(string propertyName, Type propertyType);

     public Destination() : this(0,0) { }
     public Destination(int x, int y)
     {
        myX = x;
        myY = y;
     }
     public Destination(Source copy) : this(copy, null) { }
     public Destination(Source copy, ContinueCopyCallback callback)
     {
        foreach (PropertyInfo pi in copy.GetType().GetProperties())
        {
           PropertyInfo pi2 = this.GetType().GetProperty(pi.Name);
           if ((callback == null || (callback != null && callback(pi.Name, 
              pi.PropertyType))) && pi2 != null && pi2.GetType() == pi.GetType())
           {
              pi2.SetValue(this, pi.GetValue(copy, null), null);
           }
        }
     }

     private int myX;
     public int X
     {
        get { return myX; }
        set { myX = value; }
     }

     private int myY;
     public int Y
     {
        get { return myY; }
        set { myY = value; }
     }
 }

Выходные данные дадут item2.X значение 2 и item2.Y значение 3.

Вы также можете предоставить возможность обратного вызова, которая позволит вам настраивать фильтрацию имен свойств, которые вы не хотите автоматически копировать. Также вы можете написать код для копирования в виде конструктора мелкого копирования для пункта назначения, который принимает Source в качестве параметра.

Это легкий метод, если учесть, что ваши потребности просты.

1 голос
/ 15 декабря 2009

Если типы не связаны, MiscUtil имеет:

Destination dest = PropertyCopy<Destination>.CopyFrom(source);

затем установите вручную:

dest.X = x;
dest.Y = y;

В качестве альтернативы вы можете написать метод / оператор преобразования, но вам нужно будет поддерживать его (PropertyCopy автоматически).


Re ваш пункт наследования; Я не думаю, что это хорошо подходит здесь; вы могли бы что-то сделать с частичным классом, но он больше не будет работать с LINQ-to-SQL, если вы это сделаете (он сам обрабатывает наследование, и вам это не понравится). *

0 голосов
/ 15 декабря 2009

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

Вы также можете использовать библиотеку типа AutoMapper , чтобы сделать это автоматически. Вы определяете, что источник может отображаться в пункт назначения (не более того), и он работает для вас на основе названий элементов.

В качестве альтернативы, если вы просто перемещаете данные (я полагаю, в базе данных), можете ли вы просто использовать чистый SQL для этого без необходимости какого-либо кода?

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