Использование ConditionalAttribute также удаляет вычисление аргументов?
Я попробовал следующий код:
class Magic {
[Conditional("DEBUG")]
public static void DoMagic( int stuff )
{
}
public static int ComputeMagic()
{
throw new InvalidOperationException();
}
}
class Program
{
static void Main(string[] args)
{
Magic.DoMagic(Magic.ComputeMagic());
}
}
и похоже, что в Release build исключение не генерируется, поэтому не только вызов метода, отмеченного ConditionalAttribute
удаляется, но также исключается вычисление параметров.
Такое поведение гарантировано?
2 ответа
Да, оценка аргумента удаляется, когда DEBUG
не определено (что типично для сборок Release).
С http://msdn.microsoft.com/en-us/library/aa664622%28v=vs.71%29.aspx:
Если символ определен, вызов включен; в противном случае вызов (включая оценку параметров вызова) опускается.
Да, все удалено. Это может быть полезно для избежания дорогостоящих вычислений, которые имеют отношение только к (скажем) ведению журнала, но это означает, что вы должны быть осторожны, чтобы не устранить необходимые побочные эффекты. Например:
Trace(SomethingCritical());
очень отличается от:
var result = SomethingCritical();
Trace(result);
или в вашем конкретном случае:
DoMagic(ComputeMagic()); // everything here done only if DEBUG symbol defined
против
var result = ComputeMagic(); // always done
DoMagic(result); // done only if DEBUG symbol defined
Из спецификации §17.4.2 (выделено мной):
Если символ определен, вызов включен; в противном случае вызов (включая оценку получателя и параметры вызова) пропускается.