Ich habe eine Situation, wo ich eine IEnumerable habe, die ich durchlaufen und Code für jedes Element ausführen muss.polymorphe Erweiterung zu 3rd-Party-Klassen
Dieser auszuführende Code hängt vom tatsächlichen Typ des Elements ab, und was ich suche, ist eine gute, saubere Methode, dies ohne irgendwelche Bedingungen zu tun. Wenn also die Anzahl der abgeleiteten Typen zunimmt, nehme ich zu Sie müssen einfach einen neuen Handler schreiben und meinen vorhandenen Code nicht ändern.
Um dies zu veranschaulichen ich das Beispiel, wo die 3rd-Party-Bibliothek enthält folgende Code:
public abstract class BaseObject{ }
public class Derived1: BaseObject { }
public class Derived2 : BaseObject { }
und meinem lokalen Code tut so etwas wie:
void Execute(IEnumerable<BaseObject> list)
{
foreach (var item in list)
item.DoWork();
}
ich versucht habe Schaffung Erweiterungsmethoden, um dies zu tun:
public static class Extensions
{
public static int DoWork(this BaseObject obj) { return 0; }
public static int DoWork(this Derived1 obj) { return 1; }
public static int DoWork(this Derived2 obj) { return 2; }
}
die offensichtlich nicht funktioniert, da jedes Element in der Enumeration vom Typ BaseObject ist, so wird immer die Erweiterungsmethode aufgerufen, die 0 zurückgibt.
habe ich die Möglichkeit, einen neuen abgeleiteten Typ für jeden abgeleiteten Typ alle Implementierung einer Schnittstelle zu schaffen:
public class MyDerived1: Derived1, IMyInterface
{
public int DoWork(){return 1;}
}
public class MyDerived2: Derived2, IMyInterface
{
public int DoWork(){return 2;}
}
public interface IMyInterface
{
int DoWork();
}
dann konnte ich durchlaufen und gegossen in die neue Schnittstelle:
void Execute(IEnumerable<BaseObject> list)
{
foreach (var item in list)
{
var local = item as IMyInterface;
local?.DoWork();
}
}
, aber dies erfordert die Konstruktion meines abgeleiteten Typs, und die Entscheidung, welcher Typ zu konstruieren ist, erfordert immer noch eine bedingte Anweisung, die für jeden geändert werden müsste neuer Typ hinzugefügt.
Verwenden Sie eindeutig das Fabrikmuster hier, und es ist die sauberste Lösung, die ich bisher habe.
Das Befehlsmuster bietet eine Lösung, sondern als Befehl von der Art des abgeleiteten Typs abhängig auszuführen ist, noch ein bedingter diesen Befehl zu konstruieren ist erforderlich ...
jemand einen Ansatz vorschlagen kann, das wäre Vollständig eliminieren Sie alle Bedingungen, die geändert werden müssten, wenn neue abgeleitete Typen zum Mix hinzugefügt werden?
Sie könnten ein Wörterbuch beim Start aufbauen, mithilfe von Reflektion, die Ihre Fabrik die richtige Art, ohne Notwendigkeit irgendwelcher conditionals abgeleitet erlauben würde, zu konstruieren und die Karte würde automatisch alle neuen abgeleiteten Typen, die, ohne Modifikation hinzugefügt wurden . – Baldrick
danke @Baldrick, das ist der Ansatz in der Antwort in diesem Beitrag http://stackoverflow.com/questions/27724130/simulate-inheritancity-by-extension genommen. Um ehrlich zu sein, wollte ich nicht nachdenken. – MikeW
Ich bin mir nicht sicher, ob das möglich ist. Die erforderlichen Informationen über den zugrunde liegenden Typ eines BaseObject können nicht programmatisch aufgedeckt werden, ohne dass (a) eine virtuelle Methode das Objekt selbst für eine überschriebene Methode aufruft (es ist jedoch ein Drittanbieter und kann nicht geändert werden), oder (b) Reflektieren, dann Konditional verwenden. Nicht sicher, es gibt einen anderen Weg in deiner Situation. – Baldrick