Ich hoffe, dass diese Frage nicht als zu subjektiv angesehen wird - ich erwarte nicht wirklich eine endgültige Antwort, aber ich hoffe, dass die Meinung der anderen mir zumindest dabei hilft, mir meine eigene zu bilden.
Ich implementiere ein benutzerdefiniertes Typsystem, das eine Obermenge des klassischen OOP-Typsystems ist. In diesem Typsystem können Objektinstanzen zur Laufzeit kombiniert werden, um neue Instanzen zu bilden, wobei die individuellen Identitäten erhalten bleiben.
Dieser Code:
var p = new Person();
var pa = new Partner(p);
...führt zu einem einzigen kombinierten Objekt, wobei "p" und "pa" verschiedene OOP-konforme Sichten darauf sind. D.h., die Änderung eines Eigenschaftswertes in einer der Ansichten wirkt sich sofort auf jede andere Ansicht aus, die diese Eigenschaft ebenfalls enthält.
Das alles funktioniert gut und schön, aber es fehlen zwei wichtige APIs für die Abfrage von Typ-Identitäten. Ich würde wirklich gerne in der Lage sein, solchen Code zu schreiben:
if (p is Partner)
{
(p as Partner).SomePartnerProperty = "...";
}
Das funktioniert natürlich nicht, weil das Verhalten von "is"- und "as"-Operatoren nicht über das hinaus überladen/erweitert werden kann, was die OOP-Regeln von .NET vorschreiben. Nichtsdestotrotz brauche ich diese Funktion in meinem Typsystem.
Mein erster Gedanke war, generische Erweiterungsmethoden zu verwenden, die sich an alle Instanzen meines Typsystems anhängen würden:
public static bool Is<T>(this BaseType target) where T : BaseType { ... }
public static T As<T>(this BaseType target) where T : BaseType { ... }
Abgesehen von der Frage des Namenskonflikts in Sprachen, die Groß- und Kleinschreibung nicht berücksichtigen, scheint dies in Bezug auf die Funktionalität in Ordnung zu sein:
if (p.Is<Partner>())
{
p.As<Partner>().SomePartnerProperty = "...";
}
Ich muss mich jedoch fragen, ob dies wirklich die schönste und bequemste API ist, die man sich ausdenken kann.
Was würden Sie mir raten, um diese beiden Operatoren so zu implementieren, dass sie sich im Anwendungscode natürlich anfühlen?
UPDATE : Für alle, die sich über den Zweck eines solchen Systems wundern... Im Grunde genommen fällt jeder Typ in eine von zwei Kategorien: Identität ou Rolle . In dem oben genannten Beispiel ist Person eine Identität (durch Design), während Partner eine Rolle ist (wiederum durch Design - es hätte auch anders gestaltet werden können). Die Grundregel dieses Typsystems ist, dass eine beliebige Anzahl von Rollen mit einer beliebigen Identität zusammengesetzt werden kann, während die Identität selbst nur mit einer höheren Identität zusammengesetzt werden kann (z. B. kann eine Person zu einem Kontakt, aber niemals zu einem Unternehmen werden). Ein solches Typensystem ermöglicht es Anwendungen, z. B. mit Partnerobjekten transparent umzugehen, unabhängig davon, welche Identität sie haben (z. B. Person, Firma, Bank usw.).