ブーについて聞いたことがありますか?コンパイラ パイプラインに接続できる興味深い方法があります。そのような機能の 1 つは構文属性と呼ばれます。これは、コンパイラが呼び出すインターフェイスを実装する属性であり、コード生成に参加できるようにします。
class Person:
[getter(FirstName)]
_fname as string
[getter(LastName)]
_lname as string
def constructor([required] fname, [required] lname):
_fname = fname
_lname = lname
このコードの属性は、フィールドのパブリック ゲッターと、コンストラクター パラメーターの null チェックを生成します。それはすべて、コンパイルされたアセンブリになります。
私は常に、このような拡張性を C# コンパイラの一部にしたいと考えていました。たぶん、いつかそうなるでしょう。それまでは、CciSharpなどのポストコンパイラを使用できます。CCiSharp は、Boo シンタティック属性と同様に、アセンブリ内の特別な属性に基づいてCILを書き換えます。
このコードを考えると:
class Foo {
[Lazy]
public int Value {
get { return Environment.Ticks; }
}
}
CCiSharp は、に基づいてコードを次のように変更LazyAttribute
します。
class Foo {
int Value$Value; // compiler generated
int Value$Initialized;
int GetValueUncached() {
return Environment.Ticks;
}
public int Value {
get {
if(!this.Value$Initialized) {
this.Value$Value = this.GetValueUncached();
this.Value$Initialized = true;
}
return this.Value$Value;
}
}
CCiSharp はCommon Compiler Infrastructureプロジェクトに基づいています。これは、今後の .NET Framework 4.0 でコード コントラクトポスト コンパイラを実装するために使用されるものと同じです。
これが、生成された CIL を変更する方法です。
ただし、#warning
ディレクティブには CIL 表現がなく、コンパイラ ディレクティブのみです。このディレクティブを追加するために変更する必要があるのは、生成された CIL ではなく、C# コード自体です。そのためには、C# パーサーを実装する必要があります。他の回答で述べたように、生成されたアセンブリを反映して目的の警告を発行するビルド後のイベントを作成するのが最善の選択肢だと思います。