Basierend auf der folgenden Frage, die vor einigen Tagen in SO gestellt wurde: GetType () und Polymorphismus, und als ich Eric Lipperts Antwort las , begann ich zu überlegen, ob das GetType()Nicht-Virtuelle wirklich sicherstellen würde, dass ein Objekt nicht darüber lügen kann Type.
In Erics Antwort heißt es insbesondere:
Die Framework-Designer werden keine unglaublich gefährliche Funktion hinzufügen, z. B. das Zulassen, dass ein Objekt über seinen Typ lügt, nur um es mit drei anderen Methoden desselben Typs konsistent zu machen.
Die Frage ist nun: Kann ich ein Objekt erstellen, das über seinen Typ lügt, ohne dass es sofort offensichtlich ist? Ich kann mich hier zutiefst irren und würde gerne klarstellen, ob dies der Fall ist, aber beachten Sie den folgenden Code:
public interface IFoo
{
Type GetType();
}
Und die folgenden zwei Implementierungen dieser Schnittstelle:
public class BadFoo : IFoo
{
Type IFoo.GetType()
{
return typeof(int);
}
}
public class NiceFoo : IFoo
{
}
Wenn Sie dann das folgende einfache Programm ausführen:
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();
}
Sicher genug badFoogibt eine fehlerhafte Ausgabe aus Type.
Jetzt weiß ich nicht, ob dies ernsthafte Auswirkungen hat, wenn Eric dieses Verhalten als " unglaublich gefährliches Merkmal " beschreibt, aber könnte dieses Muster eine glaubwürdige Bedrohung darstellen?
IFoo.GetTypeund object.GetTypeist nicht dasselbe, also passiert hier nichts Schlimmes außer schlechtem Stil. Bearbeiten: GetTypeWird im Allgemeinen für ein Objekt aufgerufen, das zur Kompilierungszeit in den meisten Fällen nicht bekannt ist, objectund nicht für eine zweifelhafte Benutzeroberfläche. :)
GetTypeund dieselbe Signatur haben. Das bezieht sich nicht auf die GetTypeMethode, die wichtig ist. Sie können auch eine öffentliche Instanzmethode erstellen, die die relevante GetTypeMethode mit dem newSchlüsselwort modifier verbirgt . Beachten Sie, dass wenn Sie eine generische Methode wie static Type Test<T>(T t) { return t.GetType(); }(ohne Einschränkung T) haben, Dinge wie Test<IFoo>(new BadFoo())die ursprüngliche GetTypeMethode immer noch aufrufen .