Questo non è in realtà "magico", e per quanto ne so non esiste un nome specifico per questo. È il comportamento predefinito dell'implementazione dell'interfaccia.
Il problema principale della tua domanda non è che esista una caratteristica esplicita di "digitazione anatra" che abilita questo comportamento. Il problema principale è che fraintendete ciò che un contratto di interfaccia stipula e si aspetta da qualsiasi tipo che lo implementa.
public class MyWindow : Window, IMyWindow
{
// ShowDialog is "magically" implemented by Window
}
Il fatto che tu lo chiami "magico" suggerisce che ti aspetti che un contratto di interfaccia richieda che questa classe implementi esplicitamente un determinato metodo, ma non è questo il caso.
Un esempio simile ma leggermente più semplice:
public interface ITest
{
string ToString();
}
public class Test : ITest
{
}
Il compilatore non si lamenta. Poiché ogni classe eredita intrinsecamente da object
e object
ha già un metodo string ToString()
, la classe Test
soddisfa il contratto di interfaccia perché Test
ha un metodo string ToString()
.
È un equivoco piuttosto comune di ereditarietà, in cui gli sviluppatori pensano a una classe derivata e alla sua classe base come se fossero due elementi separati di "il pacchetto completo". Ma non è questo il caso.
A tutti gli effetti, quando si considera la classe derivata, le caratteristiche che sono definite nella classe base sono uguali in ogni modo alle caratteristiche che sono definite nella classe derivata stessa. La classe derivata funzionerebbe esattamente nello stesso modo se dovessi copiare / incollare la definizione della classe base all'interno della definizione della classe derivata (invece di usare l'ereditarietà).
Consideralo come una "classe parziale parziale". Due classi parziali operano esattamente come se fossero una singola definizione di classe - non c'è differenza tra i due (a parte la possibilità di diffonderlo su più file). Per l'esempio di ereditarietà, lo chiamo "one way" perché la classe derivata include la classe base, ma la classe base non include la classe derivata.
Da un commento che hai fatto:
System.Windows.Window
does not know anything about my interface - from its point of view, the method declared in my interface just happens to coincide with one of its methods.
Ma non ti aspetti System.Windows.Window
per implementare la tua interfaccia, motivo per cui le tue aspettative sono irrilevanti.
Tutto quello che stai facendo è aspettare MyWindow
per implementare l'interfaccia IWindow
, il cui contratto può essere riepilogato come "deve avere un metodo bool? ShowDialog()
".
MyWindow
ha infatti un metodo bool? ShowDialog()
. Se definisce esplicitamente il proprio metodo bool? ShowDialog()
o ne eredita uno è assolutamente irrilevante. Il compilatore non si preoccupa del source del metodo, solo che esiste .
Pertanto il contratto ( MyWindow : IMyWindow
) è soddisfatto, quindi non si verifica alcun errore.
Come un'analogia molto semplice (e alquanto semplificata): quando voglio comprare una bevanda da $ 5, il negoziante si preoccupa da dove viene il denaro? Per esempio. Potrei pagare dalla mia eredità, avrei potuto guadagnare io stesso i soldi, l'avrei preso in prestito da un amico.
Al negoziante non importa da dove viene il denaro. A tutti i negozianti importa che ho $ 5 per pagare la bevanda.