为什么“abcd”.StartsWith(“”)返回true?

标题是整个问题。 有人能给我一个原因,为什么发生这种情况?

是的 – 因为它确实从空string开始。 的确,空string逻辑上发生在每对字符之间。

这样说:“开始”的定义是否可以解决这个问题? 这里有一个“开始”的简单定义,不包括:

“x从y开始,如果x的第一个y.Length字符与y相匹配。

另一种(等同的)定义:

“x从y开始,如果x.Substring(0, y.Length).Equals(y)

我会试着详细阐述Jon Skeet所说的。

假设x,y和z是string,+运算符实际上是串联的,那么:

如果我们可以分割z来写z = x + y,这意味着z以x开始。 因为每个stringz可以被分割为z =“”+ z,所以每个string都以“”开始。

所以,因为(“”+“abcd”)==“abcd”,所以“abcd”以“”开始

此方法将value参数与此string的开始处的子string(与该值的长度相同)进行比较,并返回一个指示它们是否相等的值。 为了平等,value必须是一个空string(Empty),对同一个实例的引用,或者匹配这个实例的开始。

.NET String.StartsWith

如果参数表示的字符序列是由此string表示的字符序列的前缀,则为true; 否则为假。 另请注意,如果参数是一个空string,或者等于由equals(Object)方法确定的此String对象, 则将返回true

Java String.startsWith

我将从一个更容易理解的相关事实开始。

空集是每个集的子集。

为什么? 如果A每个元素都是B一个元素,则子集的定义表示AB一个子集。 相反,如果A的元素不是B的元素,则A不是B的子集。

现在修理一套B 我将确定空集是B一个子集。 我将通过显示不是空集不是B的子集的情况来做到这一点。 如果空集不是B的子集,那么我可以find不在B中的空集的一个元素。 但空集没有任何元素,因此我找不到一个不在B的元素。 因此,空集不是B一个子集。 因此,空集必须是B一个子集。

任何string都以空string开始。

首先,我们必须同意我们开始的定义。 设ststring s如果s.Length >= t.Lengtht的前t字符与s字符匹配,我们说s t 开始 。 也就是说, s.Length >= t.Length并且对于每个Int32 index例如0 <= index < t.Lengths[index] == t[index]为true。 相反,我们可以说,如果声明不是从t开始的

有一个Int32 index ,使得0 <= index < t.Lengths[index] != t[index]

是真的。 用简单的英语, st短,或者,如果不是,则与s的相同位置的字符不匹配。

现在修复一个strings 。 我会build立s从空string开始。 我将通过显示s不是以空string开始的情况来做到这一点。 如果s不是以空string开始,那么s.Length < String.Empty.Lengths.Length >= String.Empty.Length并且存在一个Int32 index ,使得0 <= index < String.Empty.Length 。 但s.Length >= 0String.Empty.Length等于零,所以s.Length < String.Empty.Length不可能为true。 同样,由于“String.Empty.Length” is equal to zero, there is no satisfying 0 <= index <String.Empty.Length的Int32索引。 因此

s.Length < String.Empty.Lengths.Length >= String.Empty.Length并且有一个Int32 index使得0 <= index < String.Empty.Length

是错误的。 因此, s不是以空string开始的。 因此, s必须以空string开始。

以下是编码为string扩展的开始实现。

 public static bool DoStartsWith(this string s, string t) { if (s.Length >= t.Length) { for (int index = 0; index < t.Length; index++) { if (s[index] != t[index]) { return false; } } return true; } return false; } 

以上两个粗体的事实是真实的陈述的例子。 它们是真实的,因为定义它们的语句( 子集开头 )是对空宇宙的普遍量化 。 空集中没有元素,所以不能有空集的任何元素不在其他固定集中。 空string中没有字符,所以空string中的某个位置不能与其他固定string中的相同位置的字符不匹配。

我们只是说"abcd".StartsWith("")返回false。

如果是这样的话,那么下面的expression式是真的还是假的:

  ("abcd".Substring(0,0) == "") 

事实certificate,certificate是真实的,所以string确实从空string开始;或者换句话说,从位置0开始并具有0长度的子string“abcd”等于空string“”。 非常合乎逻辑的imo。

在C#中,这是规范告诉它做出反应的方式;

为了平等,value必须是一个空string(Empty),对同一个实例的引用,或者匹配这个实例的开始。

为什么“abcd”.StartsWith(“”)返回true?

真正的答案:

它必须是这样的,否则你会有这种情况

  "".startsWith("") == false "".equals("") == true but yet "a".startsWith("a") == true "a".equals("a") == true 

然后我们再来一遍Y2K,因为所有的银行软件都是以相同的string开头的,会让我们的账户混淆起来,突然比尔·盖茨将有我的财富,我会拥有他的,该死的! 命运对我来说并不那么友善。

两个string的前N个字符是相同的。 N是第二个string的长度,即零。

只是为了logging, String.StartsWith()内部调用System.Globalization.CultureInfo.IsPrefix()方法明确地进行以下检查:

 if (prefix.Length == 0) { return true; } 

因为一个string开始与“没有”很好。

如果你用正则expression式来思考它,这是有道理的。 每个string(不仅仅是“abcd”,还有“”和“sdf \ nff”)在计算'以空string开始'的正则expression式时返回true。

在C#中,它返回true的原因是开发者专门为它编码的。

如果您签出源代码 ,您会发现处理空string的特定逻辑:

 public Boolean StartsWith(String value) { return StartsWith(value, StringComparison.CurrentCulture); } public Boolean StartsWith(String value, StringComparison comparisonType) { ... if (value.Length == 0) { return true; }