Per l'interfaccia, l'aggiunta delle abstract
, o anche delle public
parole chiave sarebbe ridondante, quindi le ometti:
interface MyInterface {
void Method();
}
Nel CIL, il metodo è contrassegnato virtual
e abstract
.
(Notare che Java consente di dichiarare i membri dell'interfaccia public abstract
).
Per la classe di implementazione, ci sono alcune opzioni:
Non sovrascrivibile : in C # la classe non dichiara il metodo come virtual
. Ciò significa che non può essere sovrascritto in una classe derivata (solo nascosta). Nel CIL il metodo è ancora virtuale (ma sigillato) perché deve supportare il polimorfismo rispetto al tipo di interfaccia.
class MyClass : MyInterface {
public void Method() {}
}
Sostituibile : sia in C # che in CIL il metodo è virtual
. Partecipa all'invio polimorfico e può essere sovrascritto.
class MyClass : MyInterface {
public virtual void Method() {}
}
Esplicito : questo è un modo per una classe di implementare un'interfaccia ma non di fornire i metodi di interfaccia nell'interfaccia pubblica della classe stessa. Nel CIL il metodo sarà private
(!) Ma sarà comunque richiamabile dall'esterno della classe da un riferimento al tipo di interfaccia corrispondente. Anche le implementazioni esplicite non possono essere sovrascritte. Ciò è possibile perché esiste una direttiva CIL ( .override
) che collegherà il metodo privato al metodo di interfaccia corrispondente che sta implementando.
[C #]
class MyClass : MyInterface {
void MyInterface.Method() {}
}
[CIL]
.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}
In VB.NET, puoi anche creare un alias del nome del metodo di interfaccia nella classe di implementazione.
[VB.NET]
Public Class MyClass
Implements MyInterface
Public Sub AliasedMethod() Implements MyInterface.Method
End Sub
End Class
[CIL]
.method public newslot virtual final instance void AliasedMethod() cil managed
{
.override MyInterface::Method
}
Ora, considera questo strano caso:
interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }
Se Base
e Derived
sono dichiarati nello stesso assembly, il compilatore renderà Base::Method
virtuale e sigillato (nel CIL), anche se Base
non implementa l'interfaccia.
Se Base
e si Derived
trovano in assembly diversi, durante la compilazione Derived
dell'assembly, il compilatore non cambierà l'altro assembly, quindi introdurrà un membro in Derived
che sarà un'implementazione esplicita perché MyInterface::Method
delegherà semplicemente la chiamata a Base::Method
.
Quindi, vedete, ogni implementazione del metodo di interfaccia deve supportare un comportamento polimorfico, e quindi deve essere contrassegnata come virtuale nel CIL, anche se il compilatore deve fare i conti per farlo.