String类的Format重载方法,用来格式化需要的字符串非常方便。常用的重载方法原型有:

Format(String, Object)
Format(String, Object, Object)
Format(String, Object, Object, Object)
Format(String, Object[])

它们都调用了另外一个重载方法:

Format(IFormatProvider, String, Object[])

在这个方法中,调用了System.Text.StringBuilder类中的AppendFormat方法:

AppendFormat(IFormatProvider, String, Object[])

在这个方法内部对字符串进行了解析,包括我们常常利用大括号”{}”对来匹配变量参数,如:

String.Format(”this is {0}”, UserName);

不知道大家有没有在这个format参数中误用大括号的经历,比如参数本身是段脚本语句,需要使用到大括号,如:

String.Format(”return 1;} function Method{0}(){”, id);

这段代码会抛出FormatException的异常。我们察看Reflector,看看当AppendFormat方法解析这个 “return 1;} function Method{0}(){” 字符串时候,会发生什么情况:

switch (ch1) {
case ‘}’:
  if ((num1 < num2) && (chArray1[num1] == ‘}’))
    { num1++; }
  else { StringBuilder.FormatError(); }
    break;

大概在24行开始,开始判断是否是“}”字符,如果在其后没有紧跟另一个“}”符号,程序立即会抛出异常(通过StringBuilder的FormatError方法)。所以能够解释我们上面所举例子中的情况。但是根据这个反编译的源代码,就不能解释很多正常的情况,比如:

String.Format(”this is {0}”, UserName);

仔细跟踪这个AppendFormat方法,发现都会出现第49行一个数组的调用超出边界,将抛出System.IndexOutOfRangeException:

chArray1[num4++] = ch1;

不知何故,此方法在Framework中能顺利运行,难道是Reflector反编译有误?

以下为反编译的AppendFormat方法代码(真佩服写FCL的牛人,代码逻辑真是深奥阿 ):

AppendFormat


Posted on   Chagel  阅读(2823)  评论(10编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

©2005-2009. Chen Gang
点击右上角即可分享
微信分享提示