Frage

Entschuldigung, wenn dies ein Betrogene ist, aber ich konnte nicht scheinen, um die richtige Kombination aus Keywords zu bekommen dort die verschiedenen Typeinschränkung und Generika Fragen filtern nach unten (wie es viele gibt).

Ich habe zwei Schnittstellen - nennen wir sie Ionline und IOffline .

Sie sind eng miteinander verbunden, dass sie nahezu identische Verträge beschreiben, aber einer der wichtigsten Unterschiede zwischen ihnen ist der Kontext, in dem die konkreten Implementierungen verwendet werden. Es ist nicht gerade meine Verhältnisse, aber es zeigt das Problem gut.

ich dann einige Methoden gibt, die gegen die Beton-Implementierer dieser Schnittstellen funktionieren. Manchmal wollen diese Methoden nur mit einem Typ behandeln und nicht die anderen.

Einfach genug:

public void DoStuff<T>(string foo) where T : IOnline {}

Der Kicker setzt den Code für Methoden, die entweder auf Art arbeiten kann. Ich dachte, das wäre richtig, aber die Übersetzungsfehler beim Lesen, meine Erwartung, dass die Einschränkung als „erlaubt jede Art T generisch hier verwendet werden, wenn sie Ionline OR IOffline implementieren“ interpretiert werden würde, tatsächlich als „wird interpretiert wird jede Art zulassen T verwendet werden allgemein hier, wenn sie implementieren BEIDE“.

public void DoStuff<T>(string foo) where T : IOnline, IOffline {}

Der Versuch, zwei verschiedene Methoden mit dem gleichen Namen zu implementieren, aber verschiedene Einschränkungen nicht, da es offensichtlich Mehrdeutigkeit Probleme ist - sie sind eine Überlastung nicht, da die Parameterliste das gleiche ist (da das gewünschte Verhalten identisch ist).

I könnte verwendet zwei verschiedene Namen für zwei verschiedene Methoden, die jeweils mit der entsprechenden Einschränkung, aber das scheint kludgy und macht andere Dinge stromabwärts eine Nervensäge zu sein ... machbar, aber nicht ideal.

Ich fühle mich wie es etwas sein muss, ich bin hier fehlt ... Ich fühle mich in generic Land perfekt komfortabel, aber dies ist das erste Mal, dass ich zu tun habe, was ich nach, und ich fühle mich wie ich bin nur atm meine Räder drehen.

War es hilfreich?

Lösung

Die Versorgung mehrere Einschränkungen wie in Ihrem zweiten Beispiel ist in der Tat additiv. Die MSDN-Seite auf generische Einschränkungen ein wenig über diese hat.

Können Sie Ihre zwei Schnittstellen von einer Basis Schnittstelle erben machen, und die Methoden in den Basistyp einschränken?

Andere Tipps

Dies ist vielleicht nicht eine Antwort auf Ihre Frage, aber ich spontan das Gefühl, dass Sie möchten, können Sie Ihre Schnittstellen Refactoring. Aus Ihrer Frage:

  

Sie sind eng, dass im Zusammenhang sie   beschreiben nahezu identische Verträge,   aber einer der wichtigsten Unterschiede zwischen   sie ist der Kontext, in dem die   konkrete Implementierungen verwendet werden.

Meine Sicht der Schnittstellen ist, dass sie sind Verträge . Sie legen fest, wie etwas sollte aussehen , nicht genau, wie es sein sollte verhalten ; das ist die Aufgabe der Umsetzung. Jetzt habe ich keine Informationen über Ihre Anwendung oder Problemdomäne, aber ich würde wahrscheinlich versuchen, einige Zeit auf der Identifizierung identische Teile dieser Schnittstellen zu verbringen und sie in eine einzige Schnittstelle zu bewegen, und hält nur die differencies als separate Schnittstellen. Auf diese Weise können vielleicht Vergangenheit diese Art von Problemen leichter navigieren können.

Ich denke, die Standardmethode in .NET, dies zu tun, ist eine Schnittstelle zu haben, die sowohl Ihre Ionline und IOffline Funktionen enthält, und dann einige Eigenschaften, die sagen, welche Funktionen tatsächlich in einer bestimmten Klasse umgesetzt werden. Sie sehen dieses Muster in verschiedenen Orten in .NET mit Dingen wie eine Seek () -Methode, oder könnte möglicherweise nicht und eine CanSeek Eigenschaft implementiert wird, die Sie testen können.

Es ist vielleicht nicht das sauberste OO-Design, aber es funktioniert.

Verliert ein Teil der Kompilierung-Prüfung, aber ich kann jede mögliche Weise, um es nicht sehen ... Sie entscheiden müssen, was würden Sie lieber verwenden, (ich bin Ihre Präferenz vorausgesetzt Online wäre):

public void DoStuff<T>(string foo)
{
    Type type = typeof(T);
    if(type.GetInterfaces().Contains(typeof(IOnline)))
         doStuffOnline<T>(foo);
    else if(type.GetInterfaces().Contains(typeof(IOffline)))
         doStuffOffline<T>(foo);
    else
         throw new Exception("T must implement either IOnline or IOffline");
}

private void doStuffOnline<T>(string foo){ // can assume T : IOnline }
private void doStuffOffline<T>(string foo){ // can assume T : IOffline }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top