El título es toda la pregunta. ¿Alguien puede darme una razón por la que sucede esto?
Respuestas:
Sí, porque comienza con la cadena vacía. De hecho, la cadena vacía ocurre lógicamente entre cada par de caracteres.
Póngalo de esta manera: ¿qué definición de "comienza con" podría dar para excluir esto? Aquí hay una definición simple de "comienza con" que no lo hace:
"x comienza con y si los primeros y.Length
caracteres de x coinciden con los de y".
Una definición alternativa (equivalente):
"x comienza con y si x.Substring(0, y.Length).Equals(y)
"
Intentaré dar más detalles sobre lo que dijo Jon Skeet.
Digamos que x, y y z son cadenas y el operador + es de hecho una concatenación, entonces:
Si podemos dividir z para escribir z = x + y eso significa que z comienza con x. Debido a que cada cadena z se puede dividir en z = "" + z, se deduce que cada cadena comienza con "".
Entonces, debido a que ("" + "abcd") == "abcd" se sigue que "abcd" comienza con ""
Este método compara el parámetro de valor con la subcadena al comienzo de esta cadena que tiene la misma longitud que valor y devuelve un valor que indica si son iguales. Para ser igual, el valor debe ser una cadena vacía (Vacío), una referencia a esta misma instancia o coincidir con el comienzo de esta instancia.
Verdadero si la secuencia de caracteres representada por el argumento es un prefijo de la secuencia de caracteres representada por esta cadena; falso de lo contrario. Tenga en cuenta también que se devolverá verdadero si el argumento es una cadena vacía o es igual a este objeto String según lo determinado por el método equals (Object).
Comenzaré con un hecho relacionado que es más fácil de entender.
El conjunto vacío es un subconjunto de cada conjunto.
¿Por qué? La definición de subconjunto establece que A
es un subconjunto de B
si cada elemento de A
es un elemento de B
. Por el contrario, A
no es un subconjunto de B
si hay un elemento de A
que no es un elemento de B
.
Ahora arregle un juego B
. Estableceré que el conjunto vacío es un subconjunto de B
. Haré esto mostrando que no es el caso de que el conjunto vacío no sea un subconjunto de B
. Si el conjunto vacío no fuera un subconjunto de B
, podría encontrar un elemento del conjunto vacío que no está incluido B
. Pero el conjunto vacío no tiene ningún elemento y, por lo tanto, no puedo encontrar un elemento que no esté en B
. Por lo tanto, no es el caso de que el conjunto vacío no sea un subconjunto de B
. Por tanto, el conjunto vacío debe ser un subconjunto de B
.
Cualquier cadena comienza con la cadena vacía.
Primero, debemos estar de acuerdo con nuestra definición de comienza con . Let s
and t
be string
s Decimos que s
comienza con t
si s.Length >= t.Length
y los primeros t.Length
caracteres de t
coinciden con los de s
. Eso es, s.Length >= t.Length
y para todo Int32 index
eso 0 <= index < t.Length
, s[index] == t[index]
es cierto. Por el contrario, diríamos que s
no comienza con t
si la declaración
s.Length < t.Length
o s.Length >= t.Length
y hay Int32 index
tal que 0 <= index < t.Length
ys[index] != t[index]
es verdad. En inglés simple, s
es más corto que t
, o, en caso contrario, hay un carácter que t
no coincide con el carácter de la misma posición en s
.
Ahora arregle una cuerda s
. Estableceré que s
comienza con la cadena vacía. Haré esto mostrando que no es el caso que s
no comienza con la cadena vacía. Si s
no comienza con la cadena vacía, entonces s.Length < String.Empty.Length
o s.Length >= String.Empty.Length
y hay Int32 index
tal que 0 <= index < String.Empty.Length
. Pero s.Length >= 0
y String.Empty.Length
es igual a cero, por lo que es imposible s.Length < String.Empty.Length
que sea cierto. Del mismo modo, desde `` String.Empty.Length is equal to zero, there is no
Int32 index satisfying
0 <= index <String.Empty.Length`. Por lo tanto
s.Length < String.Empty.Length
o s.Length >= String.Empty.Length
y hay Int32 index
tal que0 <= index < String.Empty.Length
Es falso. Por lo tanto, no es el caso que s
no comience con la cadena vacía. Por lo tanto, s
debe comenzar con la cadena vacía.
La siguiente es una implementación de comienza con codificado como una extensión de 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;
}
Los dos hechos en negrita anteriores son ejemplos de declaraciones vacuasmente verdaderas . Son verdaderas en virtud del hecho de que los enunciados que las definen ( subconjunto y comienza con ) son cuantificaciones universales sobre universos vacíos. No hay elementos en el conjunto vacío, por lo que no puede haber ningún elemento del conjunto vacío ni en algún otro conjunto fijo. No hay caracteres en la cadena vacía, por lo que no puede haber un carácter, ya que alguna posición en la cadena vacía no coincide con el carácter en la misma posición en alguna otra cadena fija.
Digamos que "abcd".StartsWith("")
devuelve falso.
Si es así, ¿qué hace la siguiente expresión eval, verdadero o falso?
("abcd".Substring(0,0) == "")
resulta que evals a verdadero, por lo que la cadena comienza con la cadena vacía ;-), o en otras palabras, la subcadena de "abcd" que comienza en la posición 0 y tiene una longitud de 0 es igual a la cadena vacía "". En mi opinión bastante lógico.
null
habría sido un valor de retorno igualmente apropiado.
En C # así es como la especificación le dice que reaccione;
Para ser igual, el valor debe ser una cadena vacía (Vacío), una referencia a esta misma instancia, o coincidir con el comienzo de esta instancia.
¿Por qué “abcd” .StartsWith (“”) devuelve verdadero?
LA RESPUESTA REAL:
Tiene que ser así, de lo contrario, tendrías el caso donde
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
y luego tendríamos Y2K de nuevo porque todo el software bancario que depende de cadenas iguales comenzando por ellos mismos confundirá nuestras cuentas y, de repente, Bill Gates tendrá mi riqueza y yo la suya, ¡y maldita sea! El destino no es tan amable conmigo.
Solo para el registro, String.StartsWith()
llama internamente al método System.Globalization.CultureInfo.IsPrefix()
que realiza la siguiente verificación explícitamente:
if (prefix.Length == 0)
{
return true;
}
Si lo piensa en términos de expresiones regulares, tiene sentido. Cada cadena (no solo "abcd", también "" y "sdf \ nff"), devuelve verdadero al evaluar la expresión regular de 'comienza con una cadena vacía'.