我使用字符串比较来使用StringComparison.OrdinalIgnoreCase测试URL路径。
MSDN给出了以下字符串比较建议这里,但没有说明为什么要
MSDN示例(沿着上面的页面半途而废):
public static bool IsFileURI(string path)
{
path.StartsWith("FILE:", StringComparison.OrdinalIgnoreCase);
return true;
}MSDN建议:
但是,前面的示例使用String.StartsWith(String,StringComparison)方法测试相等性。由于比较的目的是测试相等性,而不是排序字符串,所以更好的替代方法是调用Equals方法,如下例所示。
public static bool IsFileURI(string path)
{
if (path.Length < 5) return false;
return String.Equals(path.Substring(0, 5), "FILE:",
StringComparison.OrdinalIgnoreCase);
}问题:为什么MSDN建议第二个示例更好?
讨论要点:
return true;是一个bug,应该是return path.StartsWith(...);。我们可以安全地忽略这一点,因为VB代码是正确的。发布于 2012-01-15 05:32:13
查看使用StartsWith的dotPeek方法,它最终调用一个比较整个字符串的内部比较函数,并根据该比较的返回值返回一个布尔值:
return TextInfo.CompareOrdinalIgnoreCaseEx(this, 0, value, 0, value.Length, value.Length) == 0;String.Equals调用:
return TextInfo.CompareOrdinalIgnoreCase(this, value) == 0;CompareOrdinalIgnoreCase调用一个dotPeek没有显示的私有方法,但我的预感是,StartsWith调用的重载遍历整个字符串,而Equals调用的重载在确定等式后立即停止。
如果需要考虑性能,请尝试使用应用程序典型的值来度量两者。
出于好奇,我试着测量这两种情况,而且看起来Equals明显地更快了。当我使用发布版本运行下面的代码时,Equals的速度几乎是StartsWith的两倍
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
var url = "http://stackoverflow.com/questions/8867710/is-string-equalsstring1-substring0-x-string2-better-than-string1-startswit";
var count = 10000000;
var http = false;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
http = url.StartsWith("http:", StringComparison.OrdinalIgnoreCase);
}
sw.Stop();
Console.WriteLine("StartsWith: {0} ms", sw.ElapsedMilliseconds);
sw.Restart();
for (int i = 0; i < count; i++)
{
http = string.Equals(url.Substring(0, 5), "http:", StringComparison.OrdinalIgnoreCase);
}
sw.Stop();
Console.WriteLine("Equals: {0} ms", sw.ElapsedMilliseconds);
Console.ReadLine();
}
}
}发布于 2012-01-15 06:31:37
答案就在您在Ordinal String Operations标题下提供的代码示例下面找到。
.NET框架中的字符串可以包含嵌入的空字符。序号比较和区域性敏感比较(包括使用不变区域性的比较)之间最明显的区别之一是如何处理字符串中嵌入的空字符。当使用String.Compare和String.Equals方法执行区分区域性的比较(包括使用不变区域性的比较)时,这些字符将被忽略。因此,在区分区域性的比较中,包含嵌入空字符的字符串可以被视为等于不包含空字符的字符串。 重要 虽然字符串比较方法忽略了嵌入的空字符,但字符串搜索方法(如String.Contains、String.EndsWith、String.IndexOf、String.LastIndexOf和String.StartsWith )却不这样做。
这意味着使用序数比较的String.StartsWith和String.Equals将返回不同的结果。也就是说,使用顺序比较的全部目的是防止土耳其系统上的人绕过安全问题(当忽略情况时,"f" != "F" )。这意味着如果测试使用了"FIL\0E:",那么仍然有人可以通过传递一个类似于String.StartsWith的文件URI来规避安全问题。
https://stackoverflow.com/questions/8867710
复制相似问题