Заголовок - это весь вопрос. Может кто-нибудь назвать мне причину, по которой это происходит?
Ответы:
Да, потому что он начинается с пустой строки. Действительно, пустая строка логически встречается между каждой парой символов.
Скажите так: какое определение «начинается с» вы могли бы дать, чтобы это исключить? Вот простое определение слова «начинается с», которого нет:
«x начинается с y, если первые y.Length
символы x совпадают с символами y».
Альтернативное (эквивалентное) определение:
"x начинается с y, если x.Substring(0, y.Length).Equals(y)
"
Я постараюсь уточнить то, что сказал Джон Скит.
Допустим, x, y и z - строки, а оператор + - это фактически конкатенация, тогда:
Если мы можем разделить z, чтобы написать z = x + y, это означает, что z начинается с x. Поскольку каждую строку z можно разделить на z = "" + z, следует, что каждая строка начинается с "".
Итак, поскольку ("" + "abcd") == "abcd" следует, что "abcd" начинается с ""
Этот метод сравнивает параметр значения с подстрокой в начале этой строки, имеющей ту же длину, что и значение, и возвращает значение, указывающее, равны ли они. Чтобы быть равным, значение должно быть пустой строкой (Empty), ссылкой на этот же экземпляр или соответствовать началу этого экземпляра.
истина, если последовательность символов, представленная аргументом, является префиксом последовательности символов, представленной этой строкой; иначе ложь. Также обратите внимание, что true будет возвращено, если аргумент является пустой строкой или равен этому объекту String, как определено методом equals (Object).
Я начну со связанного с этим факта, который легче понять.
Пустой набор - это подмножество каждого набора.
Зачем? Определение из подмножества состояний , что A
является подмножеством , B
если каждый элемент A
является элементом B
. И наоборот, A
не является подмножеством, B
если есть элемент A
, не являющийся элементом B
.
Теперь закрепим набор B
. Я установлю, что пустой набор является подмножеством B
. Я сделаю это, показав, что это не тот случай, когда пустой набор не является подмножеством B
. Если бы пустой набор не был подмножеством, B
я мог бы найти элемент пустого набора, которого нет B
. Но в пустом наборе нет никаких элементов, и поэтому я не могу найти элемент, которого нет B
. Следовательно, это не тот случай, когда пустой набор не является подмножеством B
. Таким образом, пустой набор должен быть подмножеством B
.
Любая строка начинается с пустой строки.
Во-первых, мы должны согласовать наше определение « начинается с» . Пусть s
и t
будет string
s Мы говорим, что s
начинается с t
if, s.Length >= t.Length
и первые t.Length
символы t
совпадают с символами s
. То есть, s.Length >= t.Length
и для каждого Int32 index
такого 0 <= index < t.Length
, s[index] == t[index]
это правда. И наоборот, мы бы сказали, что s
это не начинается с t
выражения if
s.Length < t.Length
или s.Length >= t.Length
и есть Int32 index
такое что 0 <= index < t.Length
иs[index] != t[index]
правда. На простом английском языке, s
короче t
, или, если нет, есть символ, который t
не соответствует символу в той же позиции в s
.
Теперь закрепите строку s
. Я установлю, что s
начинается с пустой строки. Я сделаю это, показав, что это не тот случай, s
когда строка не начинается с пустой. Если s
не начинается с пустой строки, то s.Length < String.Empty.Length
или s.Length >= String.Empty.Length
и есть Int32 index
такая, что 0 <= index < String.Empty.Length
. Но так s.Length >= 0
и String.Empty.Length
равно нулю, так что это невозможно s.Length < String.Empty.Length
. Точно так же, поскольку String.Empty.Length is equal to zero, there is no
Int32 index satisfying
0 <= index <String.Empty.Length. Следовательно
s.Length < String.Empty.Length
или s.Length >= String.Empty.Length
и есть Int32 index
такой, что0 <= index < String.Empty.Length
ложно. Следовательно, это не тот случай, s
когда строка не начинается с пустой. Таким образом, s
необходимо начинать с пустой строки.
Ниже представлена реализация, начинающаяся с закодированного как расширение 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;
}
Приведенные выше два факта, выделенные жирным шрифтом, являются примерами абсолютно истинных утверждений . Они верны в силу того факта, что определяющие их утверждения ( подмножество и начинаются с ) являются универсальными количественными характеристиками над пустыми вселенными. В пустом наборе нет элементов, поэтому не может быть никаких элементов пустого набора, которых нет в каком-либо другом фиксированном наборе. В пустой строке нет символов, поэтому не может быть символа в качестве некоторой позиции в пустой строке, не совпадающей с символом в той же позиции в какой-либо другой фиксированной строке.
Скажем так, "abcd".StartsWith("")
возвращает false.
если да, то что означает следующее выражение eval, true или false:
("abcd".Substring(0,0) == "")
оказывается, что ev принимает значение true, поэтому строка действительно начинается с пустой строки ;-), или, другими словами, подстрока «abcd», начинающаяся с позиции 0 и имеющая длину 0, равна пустой строке «». Довольно логично, imo.
null
и возвращаемое значение.
В C # спецификация предписывает ему реагировать именно так;
Чтобы быть равным, значение должно быть пустой строкой (Empty), ссылкой на этот же экземпляр или соответствовать началу этого экземпляра.
Почему «abcd» .StartsWith («») возвращает истину?
НАСТОЯЩИЙ ОТВЕТ:
Так должно быть, иначе у вас будет случай, когда
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
и тогда у нас снова будет проблема 2000 года, потому что все банковское программное обеспечение, которое зависит от равных строк, начинающихся с самих себя, перепутает наши счета, и внезапно Билл Гейтс получит мое богатство, а я его, и черт возьми! Судьба для меня не такая уж добрая.
Просто для записи String.StartsWith()
внутренне вызывает метод, System.Globalization.CultureInfo.IsPrefix()
который явно выполняет следующую проверку:
if (prefix.Length == 0)
{
return true;
}
Если вы думаете об этом в терминах регулярных выражений, это имеет смысл. Каждая строка (не только «abcd», но также «» и «sdf \ nff») возвращает истину при оценке регулярного выражения «начинается с пустой строки».