Почему “abcd”.StartsWith(“”) возвращает true?
-
02-07-2019 - |
Вопрос
Название - вот и весь вопрос.Кто-нибудь может назвать мне причину, почему это происходит?
Решение
Да - потому что он действительно начинается с пустой строки.Действительно, пустая строка логически встречается между каждой парой символов.
Скажем так:какое определение термина "начинается с" вы могли бы дать, чтобы исключить это?Вот простое определение термина "начинается с", которое не:
"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" начинается с ""
Этот метод сравнивает параметр value с подстрокой в начале этой строки той же длины, что и value, и возвращает значение, указывающее, равны ли они. Чтобы быть равным, value должно быть пустой строкой (Empty), ссылкой на этот же экземпляр или совпадать с началом этого экземпляра.
true, если последовательность символов, представленная аргументом, является префиксом последовательности символов, представленной этой строкой;в противном случае это ложь. Обратите также внимание, что значение true будет возвращено, если аргументом является пустая строка или равно этому объекту String, как определено методом equals (Object).
Я начну с связанного с этим факта, который легче понять.
Пустое множество является подмножеством каждого множества.
Почему?Тот Самый определение из подмножество заявляет , что A
является подмножеством B
если каждый элемент A
является элементом B
.И наоборот, A
не является подмножеством B
если есть элемент A
это не является элементом B
.
Теперь исправьте набор B
.Я установлю, что пустое множество является подмножеством B
.Я сделаю это, показав, что это не тот случай, когда пустое множество не является подмножеством B
.Если бы пустое множество не было подмножеством B
тогда я мог бы найти элемент пустого множества, которого нет в B
.Но в пустом наборе нет никаких элементов, и поэтому я не могу найти элемент, которого нет в B
.Следовательно, это не тот случай, когда пустое множество не является подмножеством B
.Таким образом, пустое множество должно быть подмножеством B
.
Любая строка начинается с пустой строки.
Во-первых, мы должны договориться о нашем определении понятия начинается с.Пусть s
и t
быть string
субъект Мы говорим, что s
начинается с t
если s.Length >= t.Length
и первый t.Length
характеры t
совпадают с данными из s
.Это, s.Length >= t.Length
и для каждого Int32 index
такой , что 0 <= index < t.Length
, s[index] == t[index]
это правда.И наоборот, мы бы сказали, что s
не начинается с t
если утверждение
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
чтобы быть правдой.Аналогично, поскольку `Строка.Пуста.Длинаis equal to zero, there is no
Индекс Int32satisfying
0 <= индекс < Строка.Пусто.Длина`.Следовательно
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.
если да, то чему соответствует следующее выражение, true или false:
("abcd".Substring(0,0) == "")
оказывается, что значение равно true, поэтому строка действительно начинается с пустой строки ;-), или, другими словами, подстрока "abcd", начинающаяся с позиции 0 и имеющая длину 0, равна пустой строке "".Довольно логично, имо.
В C # это то, как спецификация приказывает ему отреагировать;
Чтобы быть равным, value должно быть пустой строкой (Empty), ссылкой на этот же экземпляр или совпадать с началом этого экземпляра.
Почему “abcd”.StartsWith(“”) возвращает true?
НАСТОЯЩИЙ ОТВЕТ:
Так и должно быть, иначе у вас был бы случай, когда
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
и тогда у нас снова был бы Y2K, потому что все банковские программы, которые зависят от одинаковых строк, начинающихся с самих себя, перепутали бы наши счета, и внезапно Билл Гейтс получил бы мое богатство, а я - его, и черт возьми!Судьба просто не так добра ко мне.
Первые N символов двух строк идентичны.N - длина второй строки, т.е.ноль.
Просто для протокола, String.StartsWith()
внутренний вызов метода System.Globalization.CultureInfo.IsPrefix()
который явно выполняет следующую проверку:
if (prefix.Length == 0)
{
return true;
}
Потому что строка хорошо начинается с "ничего".
Если вы думаете об этом в терминах регулярных выражений, это имеет смысл.Каждая строка (не только "abcd", также "" и "sdf ff"), возвращает true при вычислении регулярного выражения "начинается с пустой строки".
В C # причина, по которой он возвращает true
разве что разработчики специально для этого закодировали.
Если вы посмотрите на исходный код, вы найдете конкретную логику для обработки пустой строки:
public Boolean StartsWith(String value)
{
return StartsWith(value, StringComparison.CurrentCulture);
}
public Boolean StartsWith(String value, StringComparison comparisonType)
{
...
if (value.Length == 0)
{
return true;
}