Pregunta

La C # lenguaje de especificación describe la inferencia de tipos en la sección §7.5.2. Hay un detalle en lo que yo no entiendo. Considere el siguiente caso:

// declaration
void Method<T>(T obj, Func<string, T> func);

// call
Method("obj", s => (object) s);

Tanto el Microsoft y Mono C # compiladores correctamente inferir T = object, pero mi entendimiento del algoritmo en la especificación produciría T = string y luego fallar. Así es como yo lo entiendo:

La primera fase

  • Si Ei es una función anónima, un parámetro explícito inferencia de tipos (§7.5.2.7) está hecho de Ei a Ti

    ? no tiene ningún efecto, ya que la expresión lambda no tiene ningún tipo de parámetros explícitos. ¿Verdad?

  • lo contrario, si Ei tiene un tipo U y xi es un parámetro de valor entonces a límite inferior inferencia está hecho de U a Ti.

    ? el primer parámetro es de tipo estático string, por lo que este añade string a los límites más bajos para T, ¿verdad?

La segunda fase

  • Todo sin fijar variables de tipo Xi que no hacer dependen de (§7.5.2.5) cualquier Xj son fijos (§7.5.2.10).

    ? T no es fijo; T no depende de nada ... así T debe fijarse, ¿verdad?

§7.5.2.11 Fijación

  • El conjunto de tipos de candidatos Uj comienza como el conjunto de todos los tipos en el conjunto de los límites de Xi.

    ? {string (límite inferior)}

  • A continuación, examinar cada uno con destino a Xi a su vez: [...] Para cada T límite inferior de Xi todo tipo Uj a la que no hay una conversión implícita de U se eliminan del conjunto candidato. [...]

    ? no quita nada del conjunto candidato, ¿verdad?

  • Si entre los tipos candidatos restantes Uj hay un tipo V única desde la que hay una conversión implícita a todos los otros tipos de candidatos, a continuación, Xi se fija a V.

    ? Dado que sólo hay un tipo candidato, esto es verdades vacías, por lo que Xi se fija a string. ¿Verdad?


mal Entonces, ¿dónde voy?

¿Fue útil?

Solución

ACTUALIZACIÓN: Mi investigación inicial en el autobús esta mañana fue incompleta y equivocada. El texto de la primera especificación de fase es correcta. La aplicación es correcta.

La especificación es malo en que se pone el orden de eventos equivocadas en la segunda fase. Deberíamos especificando que hacemos inferencias de tipo de salida de antes que fijamos los parámetros no dependientes.

El hombre, esto es complicado. He reescrito esta sección de la especificación más veces de las que puedo recordar.

He visto este problema antes, y recuerdo claramente la posibilidad de modificar de tal manera que el término "variable de tipo" incorrecto fue sustituido por todas partes con "parámetro de tipo". (Parámetros de tipo no son lugares de almacenamiento, cuyo contenido puede variar, por lo que no tiene sentido llamarlas variables.) Creo que al mismo tiempo me di cuenta que el orden era incorrecto. Probablemente, lo que ocurrió fue que accidentalmente enviamos una versión anterior de la especificación en la web. Muchas disculpas.

I trabajará con Mads para obtener la especificación actualizada para que coincida con la aplicación. Creo que la redacción correcta de la segunda fase debe ser algo como esto:

  • Si no hay parámetros de tipo no fijadas existe, entonces la inferencia de tipos tiene éxito.
  • En caso contrario, si no existe uno o más argumentos a la IE correspondiente tipo de parámetro Ti tal que el tipo de salida de Ei con el tipo de Ti contiene al menos un no fijado tipo de parámetro Xj, y ninguno de los tipos de entrada de Ei con el tipo Ti contiene cualquier no fijado tipo de parámetro Xj, entonces una inferencia tipo de salida se hace de todo tal Ei a Ti.

Si o no el paso anterior en realidad hizo una inferencia, nos ahora debe fijar al menos un parámetro de tipo, como sigue:

  • Si existe uno o más parámetros de tipo tal que Xi Xi no es fijo, y Xi tiene un conjunto no vacío de límites, y Xi no depende de ninguna Xj a continuación, cada uno de tales Xi es fijo. Si cualquier operación de fijación falla, entonces inferencia de tipos falla.
  • De lo contrario, si existe uno o más parámetros de tipo Xi tal que Xi no es fijo, y Xi tiene un conjunto no vacío de límites, y existe al menos un tipo de parámetro Xj que depende de Xi a continuación, cada uno de tales Xi es fijo. Si cualquier operación de fijación falla, entonces inferencia de tipos falla.
  • Si no, no somos capaces de avanzar y hay parámetros no fijadas. La inferencia de tipos falla.

Si la inferencia de tipos ni falla ni tiene éxito entonces la segunda fase se repite.

La idea aquí es que queremos asegurarnos de que el algoritmo nunca se entra en un bucle infinito. En cada repetición de la segunda fase tampoco tiene éxito, falla o no avance. Se puede no posiblemente bucle más veces de las que hay parámetros de tipo para fijar a tipos.

Gracias por llamar mi atención.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top