Почему я не могу использовать ConditionalAttribute в классе?

Я смотрю в ConditionalAttribute декларация и она объявлена ​​так:

Я нашел код JavaScript, который выглядит так:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
   AllowMultiple = true)]
public sealed class ConditionalAttribute : Attribute {
  //whatever
}

а также AttributeTargets.Class Утверждается, что это означает, что Атрибут может быть применен к классу. поэтому я попробовал это:

[Conditional("DEBUG")]
class MyClass
{
}

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

Ошибка CS1689: атрибут "System.Diagnostics.ConditionalAttribute" действителен только для методов или классов атрибутов

и MSDN говорит

Эта ошибка возникает только с атрибутом ConditionalAttribute. Как говорится в сообщении, этот атрибут может использоваться только для методов или классов атрибутов. Например, попытка применить этот атрибут к классу приведет к этой ошибке.

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

Как это возможно? Это какой-то зашитый особый случай или как?

2 ответа

Решение

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

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

Конечно, технически вы можете написать в MSIL класс без атрибутов, помеченный ConditionalAttributeскомпилируйте это с ilasm, а затем сослаться на него из проекта C# - было бы интересно узнать, что делает компилятор C#... Я предполагаю, что он не будет делать ничего особенного, если только у отдельных методов не будет метода, так как это сценарий, на который он нацелен.

Хорошо:

[Conditional("DEBUG")]
public void foo() { }

Тоже хорошо

[Conditional("DEBUG")]
public class BarAttribute : Attribute { }

Не все в порядке:

[Conditional("DEBUG")]
public class Baz { }

ConditionalAttribute может применяться к классам, но есть дополнительное ограничение класса, являющегося классом атрибута.

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

Другие вопросы по тегам