Вы когда-нибудь слышали о Бу ? У него есть интересные способы, которыми вы можете подключиться к конвейеру компилятора. Одна такая функция называется синтаксические атрибуты , которые являются атрибутами, которые реализуют интерфейс, вызываемый компилятором, чтобы они могли участвовать в генерации кода.
class Person:
[getter(FirstName)]
_fname as string
[getter(LastName)]
_lname as string
def constructor([required] fname, [required] lname):
_fname = fname
_lname = lname
Атрибуты в этом коде будут генерировать публичные методы получения для полей и нулевые проверки для параметров конструктора. Все это закончится в скомпилированной сборке.
Я всегда хотел, чтобы этот вид расширяемости был частью компилятора C #. Может быть, это когда-нибудь. До этого вы можете использовать посткомпилятор, например CciSharp . CCiSharp перезапишет CIL на основе специальных атрибутов в сборке, точно так же, как с синтаксическими атрибутами Boo.
Учитывая этот код:
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 основан на проекте Общая инфраструктура компилятора *1025*, который используется для реализации посткомпилятора кода контрактов в готовящейся .NET Framework 4.0.
Так вот как вы можете изменить сгенерированный CIL.
Но директива #warning
не имеет представления CIL, это только директива компилятора. Чтобы добавить эту директиву, необходимо изменить не сгенерированный CIL, а сам код C #. Для этого вам нужно реализовать C # парсер. Я думаю, что лучшим вариантом, как указано в других ответах, является создание события после сборки, которое отразится на сгенерированной сборке и выдаст нужное предупреждение.