5

既存のクラスのソースコードにプロパティを挿入するための自動化ツールを作成しています。たとえば、次のような既存のソースコードがあります。

public class MyClass 
{
   //class members goes here

}

このように修正したい

public class MyClass 
{
   //class members goes here

   public string MyProp { get; set; }
}

同じファイルに保存します。

クラス名、プロパティタイプ、およびプロパティ名は事前にわかっており、操作のパラメータと見なすことができます。これを簡単に行う方法はありますか?おそらく正規表現の置換はこれで機能しますが、ソースコードの新しい行、空白、インデントポリシーに関係なく、どの式を使用するかはわかりません。

編集:私が探しているのは、実行時にクラスを操作するのではなく、単にソースコードを自動的に生成することです

4

5 に答える 5

5

これを行う明確な方法は、T4 テンプレートを使用して部分クラスを生成することです。

T4 テンプレートは、コンパイル時にコードを生成するための優れた方法です。

開発者は、これらの生成されたファイルを変更しないでください。代わりに、開発者は、部分クラスのメンバーの追加定義を含む別のファイルを作成します。

そうすれば、カスタム コードをいじることなく、ジェネレーターを何度も微調整して実行できます。

于 2013-03-18T06:33:15.247 に答える
3

正規表現を使用した次のアプローチは機能するはずですが、これが必要なことを行うための最良の方法ではないと思います。本当にわかりません、それはあなたのニーズに依存します。私はいつもそれをしています(.csファイルを変更するスクリプトを作成するか、 Notepad ++からマクロを作成します)。おそらく、部分的なクラスも見てみたいと思うかもしれません。

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
    }
}

編集:ご覧のとおり、コードを正しくインデントします。クラス定義を含む行と同じ数のスペース+4つ以上を使用します。タブなどを追加する場合は、正規表現を変更できます。

于 2013-03-18T06:07:23.747 に答える
2

実行時に追加する場合

アセンブリは実行時に変更できないため、実行時にDLLを生成してロードするか、このSOの質問で説明されているようにExpandoObjectを使用する必要があります

コンパイル時に追加する場合

実行時にコードを追加したくない場合は、CodeDomを正確に探しています。

于 2013-03-18T05:40:31.240 に答える
0

実行時とコンパイル時の間に追加する場合

別のオプションを投入したかっただけです。少なくともあなたが提供したわずかな情報からすると、あなたはそれをしたくないと思っています。

IL織りを使用できます。このオプションは、(MSIL への) コンパイル後、実行前に発生します。その結果、クラスはコンパイル時の操作のすべての利点を得ることができますが、CodeDom よりもはるかに多くの情報が得られます。

MSIL ウィービングの実装には、PostSharp.Net (商用製品) とMono.Cecil (注意: Mono の部分に惑わされないでください。.Net でも動作します) が含まれます。

利点は次のとおりです。

  • その(実行時)コンパイル時の方法と同じくらい速い
  • CodeDom が失う情報がたくさんあります (部分クラスは CodeDom で特に厄介な問題です)。

欠点は次のとおりです。

  • ウィービングは難しいです(コンパイル時のチェックさえ失います)
  • ウィービング用の IDE サポートはほとんどありません
于 2013-03-18T06:23:57.077 に答える
0

Ruby で書かれた汎用コード ジェネレーターであるcogを試してみてください。cog には、目的に適した埋め込み機能があります。目標を達成するには、クラスを次のように変更します

public class MyClass 
{
    // class members goes here

    // cog: auto-properties
}

次に、コグジェネレーター (短い Ruby スクリプト) を次のように記述します。

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

この例では、 EmbedContextcのインスタンスです。ジェネレーターをセットアップしたら、コマンドライン呼び出しで実行します

$ 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 テンプレートを使用してコードを生成することもサポートしています。

于 2013-03-26T12:29:20.873 に答える