2010-06-18 114 views
2

我需要在我的MVC项目中实现一个HtmlHelper扩展,只是在DEBUG模式下输出一些字符串,而不是在RELEASE中。 我第一次尝试是:MVC助手扩展问题

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

但很明显,这将使编译错误:

"The Conditional attribute is not valid because its return type is not void."

所以我的理解是,一旦你设置[Conditional]属性,它不会允许任何返回?为什么?

有没有另一种方法来实现这种功能?任何帮助将非常感激。

回答

6

你可以使用一个preprocessor directive

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

至于你原来的问题,为什么在section 17.4.2 of the C# specification偷看表示:

[A] conditional method must have a return type of void

我只能推测出为什么设计师该语言决定了这一点,但我敢于猜测这是因为如果条件为false,C#编译器不会将方法调用编译为IL,所以实际上就好像您从未调用该方法(这会导致某些明显的问题如果预期有返回值,就会在运行时产生冲击!)

+0

完美!谢谢你,先生。 – BeCool 2010-06-18 05:34:25

+0

+1对于您如何阅读语言设计师的思想。我从来没有理解人们想如何做到这一点。也许如果我变得更老,更聪明... – 2010-06-18 08:06:57

+0

@Malcolm:语言设计师的头脑不是他正在阅读的唯一东西... – 2010-06-18 15:07:05

1

我不知道最初的设计师最初是否有这种想法,但这对我来说意义重大。

因为只能将该方法声明为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; 
} 

我会付出额外的努力来结束在预处理指令中的所有调试相关代码(包括个体的方法调用)为两个原因。首先,它提供了自己的内置文档;你确切知道什么时候,地点和原因运行。其次,如果需要修改或删除代码,则需要进行的搜索量大大减少,同时需要重复编译和重新编译以查看哪些中断。