2012-08-26 2364 views
5

Duplicar posibles:
Generic methods and method overloading¿Por qué las ambigüedades con los genéricos son inconsistentes, en lugar de generar errores?

Decir que tengo una clase como

class SortedList<K> 
{ 
    public string this[int i] { get { return "a"; /* dummy sample code */ } } 
    public string this[K key] { get { return "b"; /* dummy sample code */ } } 
} 

Ahora digamos que un tío decide utilizarlo:

static string Test1<K>(K key) { return new SortedList<K>()[key]; } 

El compilador resuelve esta llamada a la sobrecarga K key.

Ahora, el contraste con esta diciendo

static string Test2(int key) { return new SortedList<int>()[key]; } // whoops 

donde el compilador resuelve este int i a la sobrecarga.

Ahora bien, si un alma pobre dice Test1(0), obtendrá un resultado diferente si dice Test2(0), aunque los cuerpos se ven muy idénticos a primera vista.

Lo más gracioso es que, en ningún caso, el compilador o el tiempo de ejecución detectan una ambigüedad y dan un error.
En su lugar, el tiempo de ejecución simplemente cambia su comportamiento con respecto a si el valor es genérico o no, lo que puede ser claramente inesperado para la persona que llama.

¿Por qué es el comportamiento inconsistente?
O, mejor aún, ¿por qué no hay error de compilación (o tiempo de ejecución) debido a la ambigüedad?

+0

@SergRogovtsev: ¡Guau, buen descubrimiento! No lo vi; parece responder esto perfectamente.Deberíamos votar para cerrar mi pregunta entonces. – Mehrdad

Respuesta

0

¿Por qué crees que el hackeo es un comportamiento incoherente? es simplemente el punto, que ANULA el índice-getter con un captador tipo "maybe-key" ...

¿Cuál cree que es el resultado esperado? ¿una advertencia? es la necesidad del desarrollador verificar qué tipos desea usar para qué genéricos ... es lo suficientemente inteligente como para comprobar, que el método "test1" se dirigirá al getter basado en claves y test2 solo al getter basado en índices ...

que tienen ya sea a no permitir "int" tipo (con clase en restricciones por ejemplo) o un implemento otro captador método aquí ...

0

Debido a que el compilador no llama a cabo advertencias o errores sobre las cosas que sospecha que puede parecer ambiguo para ti. Llama a las cosas que encuentra ambiguas. Pero no hay nada ambiguo para el compilador aquí.

Digamos que te entrego cuadrados y rectángulos y te digo que pongas los cuadrados en el montón a y los rectángulos en el montón b. Además, no tiene que mirar los objetos para ver si son cuadrados o rectángulos porque ya están etiquetados como tales. Ahora ... en algún momento te entrego un objeto que está marcado como un rectángulo pero te das cuenta de que también es un cuadrado. Ahora, no te dije que analizaras los objetos ... Te dije que simplemente siguieras las instrucciones y los organizaras de acuerdo a cómo los etiqueté. Y así es como funciona el compilador ... haciendo exactamente lo que le dices que haga.

+0

Claro, pero ¿no puede el tiempo de ejecución dar un error? Parecería mejor que dar un comportamiento incoherente. – Mehrdad

+0

Mucha gente termina discutiendo (en pocas palabras) que el hecho de que un compilador haga algo de cierta manera debe significar que es correcto. Normalmente estoy en desacuerdo con esa lógica. Sin embargo, este caso es diferente porque dice que el comportamiento es inconsistente, pero al mismo tiempo señaló que * IS * es consistente cuando dijo que elige en función de si el valor es genérico o no. Entonces, ¿quién es realmente inconsistente aquí? : p –

+0

¿Eh? Los genéricos dan un comportamiento diferente de los no genéricos, aunque las sustituciones de tipo son las mismas. Yo llamo a eso inconsistente. – Mehrdad

Cuestiones relacionadas