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

165
Vistas
¿Por qué estos dos métodos no son ambiguos?

Esta es la firma del método Ok() en ApiController :

 protected internal virtual OkResult Ok();

Y este es mi método de mi clase RestController (que se extiende desde ApiController ):

 // Note that I'm not overriding base method protected IHttpActionResult Ok(string message = null);

Dado que OkResult implementa IHttpActionResult , ambos métodos se pueden llamar así:

 IHttpActionResult result = Ok();

De hecho, eso es lo que estoy haciendo en mi aplicación.

Mi clase PersistenceRestController (que se extiende desde RestController ), tiene estas líneas de código:

 protected override async Task<IHttpActionResult> Delete(Key id) { bool deleted = //... Attempts to delete entity if(deleted) return Ok(); else return NotFound(); }

Esto compila bien y no se genera ninguna advertencia sobre la ambigüedad del método. ¿Porqué es eso?

PersistenceRestController también ha heredado los métodos protegidos de ApiController , por lo que debería tener ambas versiones de Ok() (y las tiene).

En la ejecución, el método ejecutado es el de mi RestController .

¿Cómo sabe el compilador qué método ejecutar?

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

0

Jon Skeet respondió una pregunta similar (sin la complicación de la herencia) aquí :

Cuando el compilador tiene dos opciones iguales para elegir, usará una sobrecarga que no necesita usar ningún parámetro opcional no proporcionado en lugar de uno que sí...

Sin embargo, en su caso, se elige el método de RestController porque es la clase más derivada. Jon hace un buen trabajo al abordar el tema en detalle en su libro C# en profundidad : mire la sección de herencia de esa página, que esencialmente establece que el compilador preferirá un método en la clase de instancia real antes que métodos en clases menos derivadas.

over 4 years ago · Santiago Trujillo Denunciar

0

EDITAR:

Dejo mi respuesta original para la posteridad porque creo que te permite visualizar cosas, ¡pero NO TE CONFUNDAS! El compilador en realidad no trata el parámetro opcional como azúcar sintáctico para un método anulado. Lo trata como un método único con un parámetro opcional. La respuesta de Dusty, que menciona que "se elige el método de RestController porque es la clase más derivada", es correcta.

ORIGINAL (con ediciones visibles para la corrección):

Porque NO son ambiguos. Para ser ambiguos, los métodos deben tener la misma firma. El hecho de que el parámetro string message tenga un valor predeterminado de nulo crea efectivamente COMPORTAMIENTO como si creara dos anulaciones invocables, una de las cuales OCULTA el método original y otra claramente invocable con una cadena.

De hecho , está creando el mismo comportamiento que si fuera a hacer esto:

 public class RestController : ApiController { protected new OkResult Ok() { return Ok(null); } protected OkResult Ok(string message) { // Do your thing... } }

Encontrará que no hay forma de llamar directamente a ApiController.Ok() desde PersistenceRestController.

Si desea llamar a ApiController.Ok() desde RestController, deberá usar la palabra clave base: base.Ok();

over 4 years ago · Santiago Trujillo Denunciar

0

Mientras @DimitarTsonev y @Dusty dicen cosas verdaderas, pero su respuesta es algo entre sus respuestas. Aquí, tienes situación de herencia. Mira estas clases:

 public class Foo { public void Bar() { } } public class Foo2 : Foo{ public void Bar(string message = null) { } } public class Foo3 : Foo2{ public void Test(){ Bar(); } }

Cuando llame a Bar() en su clase Foo3 , el tiempo de ejecución buscará el método dentro de la clase Foo3 . Si lo encuentra, ejecútelo; de lo contrario, vaya a la clase superior: Foo2 y busque el método Bar . ¿Hay alguna? ¡sí! ¡así que ejecútalo! es por eso que cuando llamas a Ok , la versión de tus RestController se ejecuta.

Pero también, Foo2.Bar(string message = null) no entrará en conflicto con Foo.Bar() porque NO son ambiguos como dijo @DimitarTsonev. Entonces, su código funcionará bien.

Y, ¿qué hay de llamar a Foo.Bar() desde Foo3 ? Tienes que usar casting aquí:

 public class Foo3 : Foo2 { public void Test() { Bar(); // this will execute Foo2.Bar() } public void Test2() { ((Foo)this).Bar(); // this one will execute Foo.Bar() } }
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