2013-03-18 2 views
5

Я создаю инструмент автоматизации для вставки свойств в исходный код существующего класса. Например. У меня есть существующий исходный код, как это:Как программно вставить свойство в класс в исходном файле .cs?

public class MyClass 
{ 
    //class members goes here 

} 

Я хочу, чтобы изменить его, чтобы стать как этот

public class MyClass 
{ 
    //class members goes here 

    public string MyProp { get; set; } 
} 

и сохранить его в тот же файл.

Имя класса, тип недвижимости и имя свойства будут известны заранее и могут быть рассмотрены параметры операции. Любая идея, как это сделать легко? Возможно, regex replace будет работать для этого, но я не знаю, какое выражение использовать это будет гибким, независимо от новой строки, политики пробелов и идентификаторов исходного кода.

EDIT: То, что я ищу просто автоматически генерировать исходный код, не манипулируя классы во время выполнения

+0

Возможно, эта ссылка должна помочь вам: http://stackoverflow.com/questions/7569223/programmatically-insert-a-method-call-on-each-property-of-a-class – Falaque

+0

@Falaque На самом деле, что я «ищут», просто автоматически генерирует исходный код, а не манипулирует классами во время выполнения –

+0

, поэтому вы не хотите изменять существующий исходный код, а хотите генерировать класс с нуля? – Falaque

ответ

2

Для добавления В RunTime

Собрание не может быть изменен во время выполнения так либо вам необходимо создать DLL во время выполнения и загрузить его, либо вы можете использовать ExpandoObject, как описано в этом документе SO question

Для добавления во время компиляции

, если вы не хотите, чтобы добавить код во время выполнения, чем вы именно ищете CodeDom

+0

На самом деле, я не хочу добавлять свойство во время выполнения, а только добавлять свойство программно к исходному коду. –

+0

Или вы можете использовать файлWatch/fileSystemWatch и скомпилировать проект из строки cmd при изменении файла. – Rhexis

+0

@LouisRhys: Пожалуйста, см. Обновленный ответ – TalentTuner

3

следующий подход с использованием регулярных выражений должны работать, хотя я не думаю, что это может быть лучшим способом сделать то, что тебе нужно. Не знаю, это зависит от ваших потребностей. Я делаю это все время (либо создавая скрипты, которые изменяют файлы .cs, либо макросы от Notepad ++). Возможно, вы также можете взглянуть на partial classes.

string text = 
@"namespace X { 
    public class MyClass { 
     //Text here 
    } 
}"; 
string className = "MyClass"; 
string propertyType = "string"; 
string propertyName = "MyProperty"; 

string regex = string.Format(@"(*)((public?)\s*(static)?\s*class\s+{0}\s*{{)", className); 
string replacement = string.Format("$1$2\r\n\r\n$1 public {0} {1} {{ get; set; }}", propertyType, propertyName); 

var modified = Regex.Replace(text, regex, replacement); 
Console.WriteLine(modified); 

Приведенный выше код будет печатать:

namespace X { 
    public class MyClass { 

     public string MyProperty { get; set; } 
     //Text here 
    } 
} 

Edit: Как вы можете видеть, это сдвигает код правильно. Он использует то же количество пробелов в строке, которая содержит определение класса + 4. Если вы хотите добавить вкладку или что-то еще, вы можете изменить регулярное выражение.

+0

выглядит красиво. Любая идея, как поместить свойство в конце класса? Например. '// Текст здесь' появится поверх свойства –

+0

@LouisRhys, так что если у вас есть некоторые методы/свойства, новое свойство появится после этого? –

+0

Да, это точно цель –

0

Для добавления Между Время воспроизведения и времени компиляции

Просто хотел бросить в другом варианте. Хотя в soooo много способов, вы не хотите это делать, по крайней мере, от того, что мало информации вы дали.

Вы можете использовать ткачество IL. Эта опция выполняется ПОСЛЕ компиляции (для MSIL), но до начала выполнения. Эффекты заключаются в том, что ваш класс получает все преимущества манипулирования временем компиляции, но дает вам гораздо больше информации, чем CodeDom.

Реализации плетения MSIL включают PostSharp.Net (Коммерческий продукт) и Mono.Cecil (N.B. Не допускайте, чтобы часть Mono обманула вас, она работает и с .Net).

Преимущества:

  • его (во время выполнения) так быстро, как метод времени компиляции
  • У вас есть много информации, которая CodeDom теряет (частичные классы особенно болезненная проблема в CodeDom)

К недостаткам можно отнести:

  • ткачество трудно (вы даже потеряете время компиляции проверка)
  • Существует очень мало поддержки IDE для ткачества
5

Чистый способ сделать это, является использование T4 templates для создания partial classes.

T4 шаблоны - хороший способ генерировать код во время компиляции.

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

Таким образом, вы можете снова и снова настраивать генератор и запускать его без использования специального кода.

0

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

public class MyClass 
{ 
    // class members goes here 

    // cog: auto-properties 
} 

затем написать зубчатый генератор (короткий рубиновый скрипт), как этот

embed 'auto-properties' do |c| 
    " /* whatever you return gets injected into #{c.filename} */" 
end 

В примере, c является экземпляром EmbedContext. После того как вы установка генератор запустить его с помощью командной строки вызова

$ cog gen 
Updated src/MyClass.cs - 1st occurrence of embed 'auto-properties' 

и теперь ваш класс выглядит следующим образом

public class MyClass 
{ 
    // class members goes here 

// cog: auto-properties { 
    /* whatever you return gets injected into MyClass.cs */ 
// cog: } 
} 

Это до вас, как генерировать свойства, приведенные имя файла. cog довольно гибкий, а также поддерживает использование шаблонов ERB для генерации кода.

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