如果格式字符串的全文是静态的并且在编译时是已知的,那么丢失的格式字符串参数不应该是编译时错误,或者至少是警告吗?
ReSharper抓住了这个,但它只是一个带下划线的波浪形。我的印象是这会引发一般的编译时错误:
string x = string.Format("soeuotnh {0}");
有没有办法在不通过FxCop或其他东西运行我的代码的情况下触发此类错误的警告?即使是C / C ++编译器也会为这样一个明显的错误触发警告/错误(尽管它们通常不会检查类型安全性)。
答案 0 :(得分:2)
它可以是一个警告,但应该它?嗯,这取决于我想的编译器团队,它不像String.Format
是C#语言的一部分。
这不是C;你没有调用未定义的行为或任何东西,该方法可以简单地处理缺少的参数,并且假设是(我假设...),当它抛出异常时你会很快捕获它。它没什么“危险”,只是一个逻辑错误。
答案 1 :(得分:2)
除了你提到的自动检测这种情况之外,我认为没有任何办法。至于为什么会发生这种情况,Format方法与(String, params Object[])
重载匹配,参数为defined in the documentation,如下所示:
public static string Format(
string format,
params Object[] args
)
格式 类型:System.String
复合格式字符串(请参阅备注)。ARGS 类型:System.Object [] 包含零或更多要格式化的对象的对象数组。
由于params
定义了可变数量的参数(包括零参数),因此不会抛出编译时异常。
修改强>
由于编译器有一个有效的重载选择,因此不会出现编译时错误。因此,这不再成为编译器问题,最好的办法是使用Resharper(一种代码质量工具)来检测这种情况。
答案 2 :(得分:0)
某些C编译器将解析格式字符串,因为格式字符串与参数不匹配会导致严重的崩溃错误 - 甚至更糟的是安全漏洞。但是,在C#中,您只是在呼叫站点获得异常,因此它并不重要。
编译器可以这样做,但这需要代码将string.Format
识别为特殊情况,并且(更糟糕的是)需要有人在C#编译器中编写格式字符串解析器。所有这些都可以警告你每次执行时会崩溃的代码。
这个问题的一大问题是,许多人将所有警告和警告编译为错误,这意味着添加此警告将破坏其构建。任何在代码的黑暗角落中有一些不良格式字符串的人都会突然无法构建他们的产品。这些人会抱怨。
答案 3 :(得分:0)
正如已经说过的,这不是编译器所做或应该担心的事情。
在执行以下操作时,您期望编译器的行为如何:
string format = "{0}";
List<string> parms = new List<string> { "Hello" };
if (DateTime.Now.Second % 2 == 0)
{
format += " {1}";
parms.Add("World");
}
Console.WriteLine(format, parms.ToArray());
答案 4 :(得分:0)
Resharper显示此情况的警告:“格式化字符串中不存在的参数”。
答案 5 :(得分:-1)
方法的“format”参数不是常量。在编译时无法检查所有非常量的内容。
它可以通过各种方法在运行时编写,甚至可以是用户输入...(恐怖!)
这就是为什么它不是编译时错误。
编辑:好的,如果它是一个常量表达式,则可以进行分析并生成警告。但这里有the answer from Eric Lipert on a different question有点适用:有一个好处超过成本。
这是否值得花费String.Format(以及可能的其他字符串格式函数)的特殊情况,这是一个真正的好处......是一个艰难的调用。
答案 6 :(得分:-2)
我已经在Microsoft Connect上提交了此功能的a request for consideration,因为我觉得
在一天结束时,它是“是的,它可以,不,它没有,也许它应该”的情况。我试图确保没有我可以在编译器(而不是第三方软件)中设置的东西,以使其警告更具侵略性,或者是否有某种方式我可以更改我的代码使它抛出异常(例如,将所有内容声明为const),但事实证明(到目前为止)这是不可能的。无论Visual Studio团队对我在MS Connect上打开的问题做出的响应如何,事实上编译器当然可以在编译时捕获大量的字符串格式化异常,它会是一个好处......但是VS团队仍然需要确定它是否值得实施。