问题描述
我们最近升级的.NET 3.5的所有项目,以.NET 4我所遇到的一个比较奇怪的问题,相对于 string.IndexOf()
。
We have recently upgraded all our projects from .NET 3.5 to .NET 4. I have come across a rather strange issue with respect to string.IndexOf()
.
我的code显然做了略有不同,但在调查该问题的过程中,我发现,调用的IndexOf()
上的绳子与自身返回1而不是0。换句话说:
My code obviously does something slightly different, but in the process of investigating the issue, I found that calling IndexOf()
on a string with itself returned 1 instead of 0.In other words:
string text = "\xAD\x2D"; // problem happens with "-dely N.China", too;
int index = text.IndexOf(text); // see update note below.
给我的1,0几件事情要注意这个问题的指标,而不是:
Gave me an index of 1, instead of 0. A couple of things to note about this problem:
-
该问题似乎与这些连字符(第一个字符是统一code软连字符,第二个是一个普通的连字符)。
The problems seems related to these hyphens (the first character is the Unicode soft hyphen, the second is a regular hyphen).
我有双重检查,这种情况不会发生在.NET 3.5,但确实在.NET 4中。
I have double checked, this does not happen in .NET 3.5 but does in .NET 4.
更改的IndexOf()
做一个序对比修复的问题,因此对于一些原因,第一个字符被忽略,默认的IndexOf
。
Changing the IndexOf()
to do an ordinal compare fixes the issue, so for some reason that first character is ignored with the default IndexOf
.
有谁知道为什么会这样?
Does anyone know why this happens?
修改
对不起球员,做了一个有点东西了在原来的职位,并得到了隐藏的冲刺中就有两次。我已经更新了字符串,这应该回报指数为1,而不是2,只要您将其粘贴在正确的编辑器。
Sorry guys, made a bit of a stuff up on the original post and got the hidden dash in there twice. I have updated the string, this should return index of 1 instead of 2, as long as you paste it in the correct editor.
更新:
改变了原来的问题串一个,每一个字符是清晰可见(使用转义)。这简化了问题了一下。
Changed the original problem string to one where every actual character is clearly visible (using escaping). This simplifies the question a bit.
推荐答案
您字符串的两个字符存在:一个的(统一code code点173)和的(统一code code点45)。
Your string exists of two characters: a soft hyphen (Unicode code point 173) and a hyphen (Unicode code point 45).
维基的:根据统一code标准,则不会显示软连字符,如果该行不在该点断裂。
在使用\ XAD \ X2D.IndexOf(\ XAD \ X2D)
在.NET 4中,它似乎忽略了,你要寻找的软连字符,返回1(的 \ X2D指数
)的起始索引。在.NET 3.5中,则返回0。
When using "\xAD\x2D".IndexOf("\xAD\x2D")
in .NET 4, it seems to ignore that you're looking for the soft hyphen, returning a starting index of 1 (the index of \x2D
). In .NET 3.5, this returns 0.
更多乐趣,如果你运行此code(所以当的只有的寻找软连字符):
More fun, if you run this code (so when only looking for the soft hyphen):
string text = "\xAD\x2D";
string shy = "\xAD";
int i1 = text.IndexOf(shy);
然后 I1
变为0,而不管使用的.NET版本。 text.IndexOf(文字)的结果;
确实有所不同,这一眼看起来像我的错误。
then i1
becomes 0, regardless of the .NET version used. The result of text.IndexOf(text);
varies indeed, which at a glance looks like a bug to me.
据我可以追溯通过框架,旧的.NET版本使用的InternalCall以 IndexOfString()
(我想不出哪个API调用云),而.NET 4的以 InternalFindNLSStringEx()
制成,后者又调用<$c$c>FindNLSStringEx().
As far as I can track back through the framework, older .NET versions use an InternalCall to IndexOfString()
(I can't figure out to which API call that goes), while from .NET 4 a QCall to InternalFindNLSStringEx()
is made, which in turn calls FindNLSStringEx()
.
这个问题(我实在想不通,如果这是预期的行为)时调用 FindNLSStringEx
确实发生:
The issue (I really can't figure out if this is intended behaviour) indeed occurs when calling FindNLSStringEx
:
LPCWSTR lpStringSource = L"\xAD\x2D";
LPCWSTR lpStringValue = L"\xAD";
int length;
int i = FindNLSStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
FIND_FROMSTART,
lpStringSource,
-1,
lpStringValue,
-1,
&length,
NULL,
NULL,
1);
Console::WriteLine(i);
i = FindNLSStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
FIND_FROMSTART,
lpStringSource,
-1,
lpStringSource,
-1,
&length,
NULL,
NULL,
1);
Console::WriteLine(i);
Console::ReadLine();
打印0,然后1。注意,长度
,之后的第二个第一个呼叫,1之后的输出参数指示找到字符串的长度,为0;软连字符被计数为具有的长度为0。
Prints 0 and then 1. Note that length
, an out parameter indicating the length of the found string, is 0 after the first call and 1 after the second; the soft hyphen is counted as having a length of 0.
解决方法是使用 text.IndexOf(文字,StringComparison.OrdinalIgnoreCase);
,因为你已经注意到。这使得QCall到 InternalCompareStringOrdinalIgnoreCase()
,接着调用<$c$c>FindStringOrdinal(),这两种情况下返回0
The workaround is to use text.IndexOf(text, StringComparison.OrdinalIgnoreCase);
, as you've noted. This makes a QCall to InternalCompareStringOrdinalIgnoreCase()
which in turn calls FindStringOrdinal()
, which returns 0 for both cases.
这篇关于someString.IndexOf(someString)返回1而不是0在.NET 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!