2009-08-04 1 views
31

Я ищу способ ускорить повторяемую задачу при написании кода. У меня есть ReSharper, и я думаю, что настройка может делать то, что мне нужно.Может ли ReSharper генерировать код, который копирует свойства из одного объекта в другой?

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

Вот тип кода Я ищу сгенерировали с помощью инструмента, как ReSharper:

foo.Name = moo.Name; 
foo.Age = moo.Age; 
foo.City = moo.City; 

автоматизируя этот простой код, который копирует значения справа налево позволит сэкономить массу времени, и я думая, что ReSharper может это сделать. Тем не менее, я не видел ничего всплывающего в поисках его, хотя.

Я не ищу метод генерации кода CodeSmith или шаблон T4, потому что я хочу, чтобы он генерировал эти конкретные строки внутри моего класса, а не генерировал и весь класс или отдельный файл.

Кто-нибудь знает, как нажать несколько нажатий клавиш, ввести имена объектов «foo» и «moo» выше и заставить инструмент сгенерировать эти копии справа налево строк кода?

Update:

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

http://www.jetbrains.net/confluence/display/ReSharper/PowerToys+Pack+3.0+User+Guide

Это начинает выглядеть как выходные вызов, если кто-то еще не уже написал.

ответ

8

Я не верю, что Resharper может это сделать, но с открытым исходным кодом AutoMapper может. Новое в AutoMapper? Проверьте страницу Getting Started.

+0

Я никогда не слышал этого инструмента. С уровнями доступа к данным и Data Contracts, которые делают этот код необходимым, это отличный инструмент! – Vaccano

+2

Automapper, безусловно, отличная вещь для некоторых случаев, но может быть ОЧЕНЬ медленной для большого количества объектов. – Telavian

+7

Мы использовали Automapper в большом корпоративном приложении с тонны DTO, и через 6 месяцев мы отказались от него, потому что было сложнее поддерживать и отлаживать, чем простое старое назначение свойств. Не следует считать большим ударом по AM, но в итоге мы просто хотели сломать строку кода вместо того, чтобы зачитать большое сообщение об ошибке (сообщение об ошибке было точным и полезным). – TheDev6

-2

Простое копирование значений с одной стороны на другую довольно уродливо.

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

1

Вот простой класс для клонирования объекта. Это не совсем то, что вы просили, но, возможно, это будет полезно для вас:

//.Net 2.0 
using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Text; 

namespace YourNameSpace { 
    public static class ObjectCloner { 
     public static T Clone<T>(T obj) { 
     using (MemoryStream buffer = new MemoryStream()) { 
      BinaryFormatter formatter = new BinaryFormatter(); 
      formatter.Serialize(buffer, obj); 
      buffer.Position = 0; 
      T temp = (T)formatter.Deserialize(buffer); 
      return temp; 
     } 
     } 
    } 
} 
-1

Это та вещь, на которой Cog блестит. В основном, Cog - это инструмент создания кода. Код создается через Python.

+6

Итак, предлагая ответ на мой вопрос - использовать программу Python, чтобы помочь мне написать мой код на C#? У вас есть пример этого? – a7drew

4

Я согласен с @Ben Griswold.
В большинстве ситуаций Automapper - это путь.

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

  1. Создать новый класс и выводит из класса, из которого вы хотите скопировать свойства.
  2. Щелкните правой кнопкой мыши этот новый производный класс и выберите «Refactor> Extract Interface».
  3. Проверьте все свойства, которые хотите скопировать.
  4. Выберите «Место рядом», потому что этот интерфейс будет только временным.
  5. Нажмите «Далее».
  6. Измените производный класс, чтобы вы больше не наследовали базовый класс, и вы только реализуете свой новый интерфейс. Ожидайте увидеть красную мерцание.
  7. Наведите курсор на красную стрелку и нажмите «ALT-ENTER», чтобы «выполнить участников».
  8. Нажмите «Готово».
  9. Удалите этот временный интерфейс и измените свой класс, чтобы он больше не выполнял его.
43

Это очень просто. ReSharper не делает этого, но вы можете использовать супер-пупер REGEX!

В Visual Studio:

public string Email { get; set; } 
    public string CellPhone { get; set; } 
    public int NumChildren { get; set; } 
    public DateTime BirthDate { get; set; } 
  1. Выберите все свойства. Хит CTRL-D для копирования.

  2. Теперь нажмите CTRL-H заменить. Убедитесь, что для соответствия Regex выбрано .*.

  3. Заменить: public [\w?]* (\w*) .* (Это Regex, возможно, придется быть переделан)

  4. С: dest.$1 = source.$1;

Теперь у вас есть некоторый красивый код, который вы можете поместить в способе по вашему выбору:

dest.Email = source.Email; 
    dest.CellPhone = source.CellPhone; 
    dest.NumChildren = source.NumChildren; 
    dest.BirthDate = source.BirthDate; 
+0

Позвольте мне подключить * AutoMapper * тоже. С ним очень легко скопировать свойства. Конечно, это зависит от вашей ситуации. – Jess

+0

Абсолютно гениальный ответ, спасибо! – Mafii

8

Это несколько производное от ответа от @Jess (его регулярное выражение не работает для меня на VS2013), но вместо использования Visual Studio Я using regex101

Нажмите ссылку выше и просто вставьте свои объекты в поле Test string, и вы получите их сопоставление.

Regex Я использовал

public [A-Za-z\?]* ([A-Za-z0-9]*) .*

и заменить

Dest.$1 = Source.$1

надеюсь, что это экономит ваше время.

+0

Hi Matas. Да, я допустил для типов с нулевым значением и разбил регулярное выражение в своем ответе. Теперь он исправлен. Благодарю. – Jess

1

На основе ответа @Matas я создал более надежную версию using regex101, которая игнорирует дженерики, атрибуты и комментарии и нормализует пробелы.

Regex: *((\/+.*\n*.*)|(\[.*\]\n*.*))*public [A-Za-z\_\?\<\>]* ([A-Za-z0-9\_]*) .*(\n|)*

Заменить: $4 = person.$4,\n

Смежные вопросы