La siguiente es una pregunta de entrevista. Se me ocurrió una solución, pero no estoy seguro de por qué funciona.
Pregunta:
Sin modificar la Spartaclase, escriba un código que MakeItReturnFalsedevuelva false.
public class Sparta : Place
{
    public bool MakeItReturnFalse()
    {
        return this is Sparta;
    }
}
Mi solución: (SPOILER)
public class Place
{
public interface Sparta { }
}
Pero ¿por qué no Spartaen MakeItReturnFalse()referencia a {namespace}.Place.Spartasu lugar de {namespace}.Sparta?
                    
                        c#
                                inheritance
                                types
                                namespaces
                                
                    
                    
                        budi
fuente
                
                fuente

Respuestas:
Básicamente, porque eso es lo que dicen las reglas de búsqueda de nombres. En la especificación C # 5, las reglas de nomenclatura relevantes están en la sección 3.8 ("Espacio de nombres y nombres de tipo").
Los primeros dos puntos, truncados y anotados, se leen:
Entonces, ese último punto es lo que recoge la
Spartaclase si el primer punto no encuentra nada ... pero cuando la clase basePlacedefine una interfazSparta, se encuentra antes de considerar laSpartaclase.Tenga en cuenta que si hace que el tipo anidado sea
Place.Spartauna clase en lugar de una interfaz, aún se compila y regresafalse, pero el compilador emite una advertencia porque sabe que una instancia deSpartanunca será una instancia de la clasePlace.Sparta. Del mismo modo, si mantienePlace.Spartauna interfaz pero hace laSpartaclasesealed, recibirá una advertencia porque ningunaSpartainstancia podría implementar la interfaz.fuente
Spartaclase original ,this is Placeretornostrue. Sin embargo, agregarpublic interface Place { }a laSpartaclase hacethis is Placeque regresefalse. Hace girar mi cabeza.Placecomo la interfaz.Al resolver un nombre a su valor, la "cercanía" de la definición se utiliza para resolver ambigüedades. Cualquier definición que sea "más cercana" es la que se elige.
La interfaz
Spartase define dentro de una clase base. La claseSpartase define en el espacio de nombres que contiene. Las cosas definidas dentro de una clase base están "más cerca" que las cosas definidas en el mismo espacio de nombres.fuente
Hermosa pregunta! Me gustaría agregar una explicación un poco más larga para aquellos que no hacen C # a diario ... porque la pregunta es un buen recordatorio de los problemas de resolución de nombres en general.
Tome el código original, ligeramente modificado de las siguientes maneras:
return this is Sparta).Athenaen laPlacesuperclase para ilustrar la resolución del nombre de la interfaz.thisya que está vinculado en laSpartaclase, solo para aclararlo todo.El código se ve así:
Ahora creamos un
Spartaobjeto y llamamos a los tres métodos.El resultado que obtenemos es:
Sin embargo, si modificamos la clase Place y definimos la interfaz Sparta:
entonces es esto
Sparta, la interfaz, lo que estará disponible primero para el mecanismo de búsqueda de nombres y la salida de nuestro código cambiará a:Por lo tanto, nos hemos equivocado con la comparación de tipos en la
MakeItReturnFalsedefinición de la función simplemente definiendo la interfaz Sparta en la superclase, que se encuentra primero por la resolución de nombre.Pero, ¿por qué C # eligió priorizar las interfaces definidas en la superclase en la resolución de nombres? @JonSkeet lo sabe! Y si lee su respuesta, obtendrá los detalles del protocolo de resolución de nombres en C #.
fuente