Cambio de ruptura en la resolución de sobrecarga de método en C # 6-explicación ?


Recientemente hemos pasado de VS2013 a VS2017 en nuestra empresa. Después de la actualización, nuestro código base ya no se compilaría. Obtendríamos el siguiente error:

La llamada es ambigua entre los siguientes métodos o propiedades: 'IRepository.Get (object, params Expression > [])' y 'IRepository.Get (object, params string []) '

Aquí está la llamada en sí:

this.mainRepository.Get(newEntity.Id);

...y la definición de la interfaz:

public interface IRepository<T> where T : class
{
    T Get(object id, params Expression<Func<T, object>>[] includeExprs);
    T Get(object id, params string[] includeExprs);
}

Me preguntaba si alguien aquí podría explicar por qué este es el caso. Sospecho que la nueva Mejora la función de resolución de sobrecarga del método de C# 6.0, pero mirando las especificaciones del lenguaje no pude encontrar la regla exacta responsable del problema.

EDITAR

Escribí un post de seguimiento sobre este problema: http://codewithstyle.info/method-overload-resolution-in-c-6-0-an-interesting-bug-story

 30
Author: milosz, 2017-03-22

1 answers

Descubrí lo mismo al actualizar a Visual Studio 2015, por lo que esto no es nuevo con 2017, pero es nuevo desde 2013.

Lo reporté en github aquí:

El código que se compila en VS2013 falla con CS0121 en 2015; se sobrecarga con diferentes tipos de parámetros params#4458:

El problema es que el código es ambiguo y el nuevo compilador de Roslyn es más estricto en esto que el compilador anterior.

El problema se cerró con una acción para cambiar la documentación en lugar de volver al comportamiento anterior, como parte de issue Agregue información sobre #4458 a "Overload Resolution.md" #4922 .

En particular, AlekseyTs comentó esto:

En interés de la salud futura de nuestro código de resolución de sobrecarga, decidimos mantener el comportamiento de ruptura (y correcto). Si obtenemos más que este caso, es posible que queramos reevaluar.

Así que ahí lo tienen. El nuevo compilador es más estricto en esto y necesitas cambiar tu código.

Dado el comentario anterior de AlekseyTs, podría querer considerar reportar esto a Microsoft en github como un caso adicional. Si este tipo de problema se está extendiendo ahora que 2017 está fuera, porque mucha gente/empresas han esperado con la actualización, como el comentario dice que pueden querer reevaluar.

Además, la razón por la que no encuentras nada en la documentación (más antigua) sobre esto es que esta era una "característica oculta" del compilador anterior, como se evidencia en el cambio que hicieron a la documentación :

El antiguo compilador implementó reglas especiales para la resolución de sobrecarga (no en la especificación del lenguaje) en presencia de parámetros de matriz de parámetros no utilizados, y la interpretación más estricta de Roslyn de la especificación (ahora corregida) impidió que algunos programas compilaran.

(mi énfasis)


Cuando fijamos el mismo tipo de problema en nuestro código terminamos con algo como esto (ejemplo usando su código):

public interface IRepository<T> where T : class
{
    T Get(object id, Expression<Func<T, object>>[] tieBreaker, params Expression<Func<T, object>>[] includeExprs);
    T Get(object id, string tieBreaker, params string[] includeExprs);
}

observe la adición de los dos parámetros tieBreaker

Luego solo incluimos el parámetro explícito en la colección con los demás dentro. Si necesita poder llamar al método sin ninguno de esos parámetros adicionales opcionales, debe agregar una sobrecarga 3rd que no los tenga para ser explícito sobre qué sobrecarga se debe llamar para su interfaz final podría verse así:

public interface IRepository<T> where T : class
{
    T Get(object id);
    T Get(object id, Expression<Func<T, object>>[] tieBreaker, params Expression<Func<T, object>>[] includeExprs);
    T Get(object id, string tieBreaker, params string[] includeExprs);
}
 36
Author: Lasse Vågsæther Karlsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-22 12:57:49