Проблема расширения MVC Helper - PullRequest
2 голосов
/ 18 июня 2010

Мне нужно реализовать расширение HtmlHelper в моем проекте MVC просто для вывода какой-либо строки, но ТОЛЬКО в режиме отладки, а не в RELEASE. Моя первая попытка будет:

[Conditional("DEBUG")]
public static string TestStringForDebugOnly(this HtmlHelper helper, string testString)
{
    return testString;
}

Но очевидно, что это даст ошибку компиляции:

"Атрибут Conditional недопустим, поскольку его тип возвращаемого значения не является void."

Итак, насколько я понимаю, если вы установите атрибут [Conditional], он не позволит ничего вернуть? Почему?

Есть ли другой способ реализовать такую ​​функцию? Любая помощь будет высоко ценится.

Ответы [ 2 ]

6 голосов
/ 18 июня 2010

Вы можете использовать директиву препроцессора :

public static string TestStringForDebugOnly(this HtmlHelper helper, string testString)
{
#if DEBUG
    return "debug";
#else
    return "other";
#endif
}

Что касается вашего первоначального вопроса о том, почему, загляните в раздел 17.4.2 спецификации C # указывает:

Условный метод [A] должен иметь тип возвращаемого значения void

Я могу только догадываться, почему разработчики языка решили это, но я рискну предположить, что это потому, что компилятор C # не компилирует вызов метода в IL, если условие false, так что в действительности это как если вы никогда не вызывали метод (который мог вызвать некоторые очевидные проблемы во время выполнения, если ожидалось возвращаемое значение!)

1 голос
/ 18 июня 2010

Я не знаю, изначально разработчики исходили из этого мышления, но для меня это имеет смысл.

Поскольку вы можете объявить метод только как тип void И он не можетбыть переопределенным И на него нельзя ссылаться как на часть интерфейса, компилятор может просто игнорировать метод, потому что он не будет иметь зависимостей, если указанный режим не соответствует.Если другой метод вызывает его в режиме несоответствия, компилятор может просто обработать его как недопустимый вызов метода, как если бы атрибута не было.

Пример Джона будет работать, но я бы сделал что-то вроде этого:

#if DEBUG
public static string TestStringForDebugOnly(...)
{
    ...
}
#endif

// Arguments are only for illustration.
public string CallingMethod(int id, string temp)
{

    #if DEBUG
    string result = TestStringForDebugOnly(id, temp);
    #else
    string result = TestString(id, temp);
    #endif

    return result;
}

Я бы потратил дополнительные усилия, чтобы обернуть весь код, связанный с DEBUG (включая вызовы отдельных методов), в директивы препроцессора по двум причинам.Во-первых, он предоставляет собственную встроенную документацию;Вы точно знаете, что должно выполняться, когда, где и почему.Во-вторых, если код необходимо изменить или удалить, объем поиска, который необходимо выполнить, значительно сокращается, наряду с необходимостью многократной компиляции и повторной компиляции, чтобы увидеть, что ломается.

...