c# - overload - Método de sobrecarga y herencia
overload in c# (2)
Tengo las siguientes clases:
public class BaseRepository
{
public virtual void Delete(int id)
{
Console.WriteLine("Delete by id in BaseRepository");
}
}
public class EFRepository: BaseRepository
{
public override void Delete(int id)
{
Console.WriteLine("Delete by Id in EFRepository");
}
public void Delete(object entity)
{
Console.WriteLine("Delete by entity in EFRepository");
}
}
Entonces lo uso como:
var repository = new EFRepository();
int id = 1;
repository.Delete(id);
¿Por qué en ese caso solo EFRepository.Delete(object entity)
?
Básicamente, la forma en que la invocación de método funciona en C # es que el compilador busca primero la clase más derivada y ve si los métodos recientemente declarados (sin incluir anulaciones) son aplicables para los argumentos de la llamada. Si hay al menos un método aplicable, se resuelve la resolución de sobrecarga, que es la mejor. Si no lo hay, prueba la clase base, y así sucesivamente.
Estoy de acuerdo en que esto es sorprendente, es un intento de contrarrestar el problema de la "clase base frágil", pero personalmente preferiría que cualquier método anulado se incluyera en el conjunto de candidatos.
La invocación al método se describe en la sección 7.6.5.1 de la especificación C # 5. Las partes relevantes aquí son:
- El conjunto de métodos candidatos se reduce para contener solo métodos de los tipos más derivados: para cada método
CF
en el conjunto, dondeC
es el tipo en el que se declara el métodoF
, todos los métodos declarados en un tipo base deC
se eliminan de el conjunto. Además, siC
es un tipo de clase distinto de objeto, todos los métodos declarados en un tipo de interfaz se eliminan del conjunto. (Esta última regla solo tiene efecto cuando el grupo de métodos fue el resultado de una búsqueda de miembros en un parámetro de tipo que tiene una clase base efectiva distinta de un objeto y un conjunto de interfaz efectivo no vacío.)
Y en la parte de búsqueda de miembros de 7.4, los métodos de override
se eliminan explícitamente:
Los miembros que incluyen un modificador de
override
se excluyen del conjunto.
Porque: public override void Delete (int id) solo anulará el método de la clase base, cuál es: public virtual void Delete (int id).
Mientras que public void Delete (entidad de objeto) es el método de clase EFRepository , entonces cuando ejecutas el método desde el objeto EFRepository invocará a un método propio que no es más que el vacío público Delete (entidad de objeto)