Basandomi sulla seguente domanda posta qualche giorno fa in SO: GetType () e polimorfismo e leggendo la risposta di Eric Lippert , ho iniziato a pensare se il fare GetType()non essere virtuale assicurasse davvero che un oggetto non potesse mentire al riguardo Type.
Nello specifico, la risposta di Eric afferma quanto segue:
I progettisti del framework non aggiungeranno una funzionalità incredibilmente pericolosa come consentire a un oggetto di mentire sul suo tipo semplicemente per renderlo coerente con altri tre metodi dello stesso tipo.
Ora la domanda è: posso fare un oggetto che fa menzogna il suo tipo, senza che sia immediatamente evidente? Potrei sbagliarmi profondamente qui e mi piacerebbe un chiarimento se questo è il caso, ma considera il seguente codice:
public interface IFoo
{
Type GetType();
}
E le seguenti due implementazioni di detta interfaccia:
public class BadFoo : IFoo
{
Type IFoo.GetType()
{
return typeof(int);
}
}
public class NiceFoo : IFoo
{
}
Quindi se esegui il seguente semplice programma:
static void Main(string[] args)
{
IFoo badFoo = new BadFoo();
IFoo niceFoo = new NiceFoo();
Console.WriteLine("BadFoo says he's a '{0}'", badFoo.GetType().ToString());
Console.WriteLine("NiceFoo says he's a '{0}'", niceFoo.GetType().ToString());
Console.ReadLine();
}
Abbastanza sicuro badFooemette un errore Type.
Ora non so se questo ha delle implicazioni serie sulla base del fatto che Eric descrive questo comportamento come una "caratteristica incredibilmente pericolosa ", ma questo modello potrebbe rappresentare una minaccia credibile?
IFoo.GetTypee object.GetTypenon è la stessa cosa, quindi qui non sta succedendo niente di brutto tranne lo stile povero. Modifica: in genere GetTypeverrà chiamato su qualche oggetto non noto in fase di compilazione, nella maggior parte dei casi objecte non su qualche interfaccia dubbia. :)
GetType, con la stessa firma. Ciò non riguarda il GetTypemetodo che è importante. Puoi anche creare un metodo di istanza pubblico che nasconda il GetTypemetodo pertinente , utilizzando la newparola chiave modificatore. Nota, se hai un metodo generico come static Type Test<T>(T t) { return t.GetType(); }(senza vincoli T), cose come Test<IFoo>(new BadFoo())chiameranno ancora il GetTypemetodo originale .