2010-11-30 13 views
9

Bajo observaciones it, dice¿Es string.ElementAt() O (1)?

Si el tipo de fuente implementa IList, que la aplicación se utiliza para obtener el elemento en el índice especificado. De lo contrario, este método obtiene el elemento especificado.

String no implementa IList<T>. ¿Eso significa que esta será una operación O(n) si declaro algo como,

IEnumerable<char> myString = "stringy"; 

?

+1

Esto lleva a la interesante pregunta de por qué 'string' no implementa' IList '. – CodesInChaos

+0

@CodeInChaos: Pensé en eso también, pero supongo que es porque las cadenas son inmutables. No puede tener esos métodos 'Add' y' Remove'. – mpen

+1

@Ralph IList tiene una propiedad IsReadOnly. Y los métodos de mutación se implementarían explícitamente (para que no aparezcan en 'string' en sí mismos) y lanzaran una' NotSupportedException'. Aún así, creo que es un error de diseño en .net no tener interfaces de sólo lectura para Collection/List. – CodesInChaos

Respuesta

7

ElementAt cuando se aplica a un tipo que es string será una operación O (N). No implementa IList<char> y, por lo tanto, ElementAt no realizará ninguna optimización en él y en su lugar se enumerará a través del IEnumerable<char> hasta que alcance el índice especificado.

+1

No hay implementación de caso especial para cadena? Eso apesta :( – mpen

+1

@Ralph en general los métodos LINQ no implementan casos especiales para typse concreto pero en cambio para interfaces. – JaredPar

+3

¡La cadena es tan común!: P Todavía es especial en mi corazón, incluso si linq no lo reconocerá como – mpen

1

Dado que la cadena no está implementando IList pero IEnumerable<char> ElementAt ejecutará el siguiente código:

using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 

y GetEnumerator en cadena recupera una CharEnumerator que es O (n) a medida que se supone.

Si desea una mejor aplicación crear su propio método de extensión

public static class StringExt 
{ 
    public static char ElementAt(this string input, int index) 
    { 
     if (index < input.Length) return input[index]; 
     throw new IndexOutOfRangeException(); 
    } 
} 

que supongo es O (1), pero es difícil decir desde el descriptor de acceso índice en cadena se realiza en código no seguro.

+0

Solo, para su información, su método de extensión es inútil si se extiende solo una cadena;) – mpen

+0

Puede cambiarle el nombre a ElementsAt, y elegirá su implementación específica antes que la Linq.A continuación, agregue versiones específicas según sea necesario. –

Cuestiones relacionadas