以下内容将在运行时抛出异常:
string s = string.Format("{0} {1} {2} {3} {4}",1,2,3,4);
但它会成功构建。为什么呢?
答案 0 :(得分:5)
String.Format
超过3个参数使用params
语法,因此所有参数都像数组一样传递,没有运行时检查项目数是否符合格式:
public static string Format(string format, object arg0);
public static string Format(string format, object arg0, object arg1);
public static string Format(string format, object arg0, object arg1, object arg2);
public static string Format(string format, params object[] args);
答案 1 :(得分:3)
在一般情况下,格式字符串不一定是字符串文字,编译器不可能知道是否提供了足够的参数。
在这种特定的情况下,编译器可以知道,但是在哪些情况下描述它应该被视为编译时错误的成本相当高并且存在C#的碎片化的风险,其中一些C#代码用一个编译器编译并且与另一个失败。至少有三种不同的C#编译器可以在现实世界中使用,它们应该遵循相同的规范。即使在编译时已知问题的情况下,将此视为运行时错误也可能是最不好的解决方案。
答案 2 :(得分:2)
因为string.Format()
为超过3个参数(params
语法)采用变量参数列表,并且编译器没有“查看”格式说明符字符串。
如果您安装了Resharper,它会将这些标记为错误,
答案 3 :(得分:1)
编译器在这里的工作是解析一个匹配所提供参数的相应string.Format方法,让我考虑适用的方法组,签名,转换运算符等 - 并生成适当的IL来实现这一点。编译器不关心字符串中的内容。语言规范未提及string.Format
或任何恰好与之相关的{n}
等规则。对于编译器,它只是要提供给ldstr
的数据。
有些工具可以 发现这个(例如resharper),但是:编译器对此字符串中的内容并不感兴趣。