C# - Erweiterung Methode auf Typ Mit Generic Type Arguments
Ich bin auf der Suche nach wegen zur Verbesserung der Kohärenz, der Vereinfachung und der Lesbarkeit von code in der Anwendung an der ich arbeite. Der Start-code sah so etwas wie dieses:
context.GetGraphType<Bar>().Subscribe<Fizz>(
(instance, evt) => evt.Execute((Bar)instance.Instance)
);
Gibt es eine Reihe von nahezu identische code-Zeilen wie die oben genannten. Ich wollte umschreiben, dass es so Aussehen:
typeof(Bar).SubscribeTo<Fizz>(context);
Für eine Sache, das würde mir erlauben, zu nutzen, zu formalisieren, was bereits zu einem informellen übereinkommen. Auch habe ich gehofft, es würde nun etwas gelesen wie "bar abonniert die fizz-event auf den gegebenen Kontext", sondern als "Kontext bekommt die bar-Typ und abonniert fizz und dann tut einige Sachen." Ich denke, dass der flow ist besser, und die Mitarbeiter, die ich gefragt vereinbart.
Ich begann zu implementieren dies als eine Erweiterung-Methode. Um zu erreichen die oben, wollte ich machen Verwendung von eine abstrakte generische Basisklasse für die Veranstaltung geben, so Fizz
wäre Event<T>
. Dies würde bedeuten, dass der generische Typ-argument für die Erweiterung Methode müsste eingeschränkt werden, der Art, dass die extension-Methode aufgerufen wird. Also für das obige Beispiel Fizz
müsste der Typ Event<Bar>
.
Ist das möglich? Ich ging mit einer alternativen Lösung in der Zwischenzeit, aber ich bin immer noch neugierig, ob es erreicht werden kann. Andere Vorschläge sind willkommen, wie gut.
Dank!
Edit #1: Nur um klar zu sein, ich weiß, dass ich könnte eine zusätzliche Typ-parameter, aber ich bin auf der Suche nach Möglichkeiten, Sie zu vermeiden, wenn möglich.
Edit #2:
Ich denke, ich werde gehen, mit einer leichten variation der akzeptierten Antwort, denn es entspricht nicht 100% mit meinem Szenario. Die Quintessenz ist, dass eine generische statische Klasse kann stattdessen verwendet werden, der eine Erweiterung Methode des Typs zu erreichen, ist mein Ziel. Dank dss539!
Update-code (es kann sein, Tippfehler, seit ich das hier mache, on-the-fly):
public class Bar { }
public class Event<TSubscriber>
{
public abstract void Execute(TSubscriber source);
}
public class Fizz : Event<Bar>
{
public override void Execute(Bar bar)
{
//respond to event
}
}
public class Context { }
public static class ForType<TSubscriber>
{
public static void SubscribeTo<TEvent>(Context context)
where TEvent : Event<TSubscriber>
{
context.GetType<TSubscriber>().Subscribe<TEvent>(
(evt, args) => evt.Execute((TSubscriber)args.Source));
}
}
public static void Run()
{
ForType<Bar>.SubscribeTo<Fizz>(context);
}
- Ich verstehe nicht ganz deine Frage. Was macht Ihre vorhandene Signatur der Methode Aussehen?
Subscribe<T>(this Type type, Action<T, Fizz>)
? Wenn Sie zeigen, was Sie haben(oder gleichwertig), die möglicherweise helfen, zu erklären. - Ich glaube, ich hatte ein ähnliches design-Problem eine Weile zurück. Viel Glück 🙂
- Es wäre mehr wie Abonnieren<T>(dieser Typ, Context ctx). Das problem ist, dass es keine Möglichkeit gibt (die ich kenne) zu beschränken, dass T vom Typ Event<geben Sie "type" - parameter>.
- es klingt wie Sie versuchen, access-Laufzeit-Informationen, die beim kompilieren/Bearbeiten Zeit. Der Typ-parameter muss kein Wert erst zur Laufzeit.
- Das ist, was ich dachte, wollte nur die Bestätigung und eine gute Erklärung, das war mehr als eine Ahnung oder Vermutung. Und vielen Dank für eine hervorragende Antwort! Akzeptiert...
- danke für den Hinweis
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist nicht genau wie Sie gefragt, aber vielleicht wird es ausreichen.
Warum nicht etwas ein bisschen mehr idomatic, wo man generische constraints, die Regeln durchzusetzen:
Die Aufrufe Aussehen würde:
Die Einschränkung
where TEvent : Event<TSub>
sichert die Beziehung zwischen dem Ereignis und Abonnement-Typ, den Sie wünschen. Es ist auch vorzuziehen, die in meinem Buch eine extension-Methode auf die KlasseType
- weil, die neigt zu Unordnung intellisense.Type
ist in vielen Situationen, und mit fadenscheinigen Methoden in Intellisense angezeigt, die auf alle Instanzen vonType
eher verwirrend. Es ist auch nicht offensichtlich für den Verbraucher der Bibliothek, die Sie auf diese Weise "abonnieren" - es sei denn, Sie haben tatsächlich gesehen, wie ein code-Beispiel für Sie.Kann man wahrscheinlich schließen, erweitern
System.Type
(habentypeof(T).
) und hinzufügen (Erweiterung) - Methode, um Rahmen, die verwandelt .NET-Typ auf Ihrer internen Darstellung (gleiche zurückgegeben durchGetGraphType
)....