Условный метод, вызывающий условный метод, не работает в С#

Я пытаюсь улучшить свой класс Logger с помощью некоторых условий, чтобы контролировать, что и где регистрировать. У меня есть два вида функций ведения журнала:

public static class Logger
{
    [Conditional("Logging"), Conditional("VerboseLogging")]
    public static void Log(string msg, string filename)
    {
        // log to file
    }

    [Conditional("VerboseLogging")]
    public static void VerboseLog(string msg, string filename)
    {
        Log(msg, filename); // just defer call to Log(string msg)
    }
}

Однако запуск следующей программы

#define Logging
#define VerboseLogging

static void Main(string[] args)
{
    Logger.Log("Logging", "");
    Logger.VerboseLog("VerboseLogging", "");
}

выдает только вывод «Ведение журнала», отсутствует «Подробное ведение журнала».

Отладка приложения показала, что VerboseLogging действительно вызывается, но не вызывает Log(msg, filename). Отладчик просто перескакивает прямо через вызов функции в конец функции VerboseLog().

Когда я удаляю условные операторы из метода Log(string msg), он работает.

Кто-нибудь знает, почему это происходит или что делать, чтобы это называлось?


person Michael Klement    schedule 23.04.2009    source источник
comment
Я создал приложение именно так, как оно есть у вас, и все работало как надо; Я не могу воссоздать проблему, с которой вы столкнулись.   -  person Jeff Yates    schedule 23.04.2009
comment
Возможно, бинарник не пересобрал должным образом? Пробовали делать чистую сборку?   -  person Jeff Yates    schedule 23.04.2009
comment
Да, я уже пробовал это несколько раз. Конечно, в моем приложении есть еще кое-что, чтение CSV, запись в файл и т. д. Я не понимаю, почему оно вызывает VerbosLog(...), но перескакивает через вызов Log() в теле VerboseLog().   -  person Michael Klement    schedule 23.04.2009


Ответы (3)


Обратите внимание, что вам также необходимо определить Logging и VerboseLogging в файле Logger , потому что VerboseLog не будет вызывать Log, если Logging там не определено.

Чтобы добавить условное определение для всего проекта, щелкните правой кнопкой мыши свой проект и выберите «Свойства проекта». Затем перейдите на вкладку «Сборка» и введите «Ведение журнала, Подробное ведение журнала» в текстовое поле «Символы условной компиляции».

person Groo    schedule 23.04.2009

Там условные предложения не перевернуты? то есть

[Conditional("Logging")]
public static void Log(string msg, string filename) { }

[Conditional("Logging"), Conditional("VerboseLogging")]
public static void VerboseLog(string msg, string filename) {
    Log(msg, filename); // just defers call to Log()
}
person Eoin Campbell    schedule 23.04.2009
comment
Нет, я так не думаю. OP хочет, чтобы Log возникал в обеих ситуациях, но VerboseLog возникал только для условия VerboseLogging. - person Jeff Yates; 23.04.2009
comment
Несмотря на это, у него по-прежнему определены VerboseLogging и Logging. - person Josh G; 23.04.2009
comment
Джефф Йейтс прав. Журнал должен происходить в обоих случаях, VerboseLog — только в том случае, если определен VerboseLogging. - person Michael Klement; 23.04.2009
comment
@Josh G: Да, но это не вредит. Даже если я определяю только VerboseLogging, он все равно не работает :( - person Michael Klement; 23.04.2009
comment
msdn.microsoft.com/en-us/library/4xssyw96.aspx имеет некоторую информацию о логическом И/ИЛИ поведении условных выражений, но, судя по тому, что я прочитал на этой странице... ваш пример должен работать - person Eoin Campbell; 23.04.2009

Никакой реальной помощи, но код, который вы разместили, отлично работает здесь для меня (консольное приложение .NET 3.5 SP1). Конечно, мне нужно удалить параметр имени файла, поскольку ваши вызовы в main не предоставляют его, но кроме этого оба определения дали мне оба журнала, а удаление подробного определения записало только «Ведение журнала».

Применение бритвы Оккама к проблеме: поскольку код, который вы разместили, очевидно, не является прямым из вашего источника (нет тела для метода журнала и отсутствующих параметров), вы уверены, что правильно написали определения в ваш первоисточник? Кроме этого, я понятия не имею, почему это не работает для вас...

person Martin Harris    schedule 23.04.2009
comment
Спасибо за тестирование кода! Я везде скопировал VerboseLogging, все равно не работает. Как ни странно, метод VerboseLog() ДЕЙСТВИТЕЛЬНО вызывается, но он не вызывает Log() внутри тела. Он перепрыгивает через него. - person Michael Klement; 23.04.2009
comment
Ах, теперь, когда был опубликован настоящий ответ, я вижу, что срезать углы и помещать все классы в один исходный файл было не самым разумным способом проверить эту проблему. Живи и учись, наверное... - person Martin Harris; 23.04.2009