Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

287
Vistas
Cambio importante en la resolución de sobrecarga del método en C# 6: ¿explicación?

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

La llamada es ambigua entre los siguientes métodos o propiedades: 'IRepository<T>.Get(object, params Expression<Func<T, object>>[])' e 'IRepository<T>.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 función de resolución de sobrecarga del método mejorado de C# 6.0, pero mirando la especificación del idioma, no pude encontrar la regla exacta responsable del problema.

EDITAR

Escribí una publicación de blog de seguimiento sobre este problema: http://codewithstyle.info/method-overload-solution-in-c-6-0-an-interesting-bug-story

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Descubrí lo mismo cuando actualicé a Visual Studio 2015, por lo que no es nuevo con 2017, pero es nuevo desde 2013.

Lo informé en github aquí:

El código que se compila en VS2013 falla con CS0121 en 2015; sobrecargas con diferentes tipos de parámetros de parámetros # 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 del problema Agregar información sobre #4458 a "Sobrecargar resolución.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 interrupción (y correcto). Si obtenemos más que este único caso, es posible que deseemos reevaluar.

Así que ahí lo tienes. El nuevo compilador es más estricto en esto y necesita cambiar su código .

Dado el comentario anterior de AlekseyTs, es posible que desee considerar informar esto a Microsoft en github como un caso adicional. Si este tipo de problema se está volviendo más generalizado ahora que terminó 2017, porque muchas personas/empresas han esperado con la actualización, como dice el comentario, es posible que deseen reevaluar.

Además, la razón por la que no encuentra nada en la documentación (más antigua) sobre esto es que se trataba de una "característica oculta" del compilador anterior, como se desprende del cambio que hicieron en 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 se compilaran algunos programas.

(mi énfasis)


Cuando solucionamos 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 simplemente 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 tercera sobrecarga que no los tenga para ser explícitos sobre qué sobrecarga debe llamarse para que su interfaz final se vea 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); }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda