Acabo de descompilar alguna interfaz de terceros y me rasqué la cabeza sobre lo siguiente:

public interface IFoo 
{
    string Name { get; set; }
}
public interface IBar : IFoo
{
    new string Name { get; set; }
}

Como puede ver, tengo dos interfaces, donde IBar extiende IFoo al ocultar su propiedad Name -. Sin embargo, no puedo ver qué hace la new palabra clave aquí. Leí una respuesta de Eric Lippert que se refiere a miembros que solo difieren en su tipo de retorno. Sin embargo, en mi caso, todo es solo una cadena.

Por supuesto, podríamos implementar explícitamente cualquiera de las interfaces. Pero eso sería posible sin new de todos modos.

1
HimBromBeere 2 dic. 2019 a las 11:44

2 respuestas

La mejor respuesta

El campo de nombre en IFoo e IBar son diferentes, puede implementar dos nombres en una clase:

public interface IFoo
{
    string Name { get; set; }
}
public interface IBar : IFoo
{
    new string Name { get; set; }
}

public class Implementation : IBar
{
    string IBar.Name { get; set; } = "Bar";

    string IFoo.Name { get; set; } = "Foo";
}

Si lanza la clase de Implementación a IBar, el valor será Bar y si la lanza a IFoo, el valor será Foo.

0
Leisen Chang 2 dic. 2019 a las 08:54

Las interfaces no tienen herencia o una idea de sobrescribir algo. Todo lo que evita aquí con el "nuevo" es un conflicto de nombres. Implementa una nueva propiedad, con el mismo nombre. Todo lo demás funcionará como de costumbre.

Al implementar IBar en una clase, tiene la posibilidad de definir una propiedad pública, esto servirá como ambas propiedades de Nombre. El algoritmo de definición implícita de una interfaz funciona desde la vista de la interfaz. El compilador de C # busca un nombre de propiedad 'Nombre' para IFoo y busca nuevamente IBar, y de repente encuentra la misma propiedad para ambos.

Alternativamente, declara los miembros de la interfaz explícitamente y puede adjuntar dos implementaciones diferentes de 'Nombre', si lo desea.

Esto explica también por qué siempre debe nombrar la definición explícita con su tipo de definición. Debe implementar explícitamente IFoo.Name e IBar.Name, no está oculto de ninguna manera, puede tener acceso desde el exterior, dependiendo de qué Cast a qué interfaz esté utilizando. Es como si definiera el "Nombre" de una clase en dos espacios de nombres diferentes, la misma idea aquí.

Es menos probable que se te ocurra esta pregunta en VB.Net, porque allí cada implementación de interfaz es explícita.

1
Holger 2 dic. 2019 a las 08:53