你有沒有聽說過Boo?它有一些有趣的方法可以讓你連接到編譯器管道。一種這樣的特性叫做syntactic attributes,它們是實現編譯器調用的接口的屬性,以便它們可以參與代碼生成。
class Person:
[getter(FirstName)]
_fname as string
[getter(LastName)]
_lname as string
def constructor([required] fname, [required] lname):
_fname = fname
_lname = lname
此代碼中的屬性將爲字段生成公共getter,併爲構造函數參數生成null檢查。它將在編譯後的程序集中結束。
I've always wanted這種可擴展性成爲C#編譯器的一部分。也許它會有一天。在此之前,您可以使用後編譯器,如CciSharp。 CCiSharp將根據程序集中的特殊屬性重寫CIL,就像使用Boo synctatic屬性一樣。
鑑於此代碼:
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項目,用於實現code contracts後相同編譯器在即將到來的.NET Framework 4.0中。
所以這就是你如何改變生成的CIL。
但是,#warning
指令沒有CIL表示,它只是一個編譯器指令。要添加此指令,必須進行變異的不是生成的CIL,而是C#代碼本身。你必須爲此實現一個C#解析器。我認爲最好的辦法是,在其他應答指出,創建一個生成後事件,這將反映在生成的程序集,併發出警告所需。
我想我明白你在說什麼,你想要一個自定義屬性應用於一個方法,併發出一個#warning指令,如果條件滿足..我不認爲你可以這樣做,因爲#warning是一個編譯時間指令.. – t0mm13b 2010-01-30 20:02:43
的方式很好的問題... +1從我... – t0mm13b 2010-01-30 20:05:52