Frage

C # 3.0 und .NET 3.5, vorstellen, gibt es eine Schnittstelle:

public interface INameable
{
  string Name {get;}
}

und viele unveränderlichen Klassen, die die Schnittstelle implementieren.

Ich möchte eine einzige Erweiterungsmethode haben,

public static T Rename<T>(this T obj) where T : INameable
{ 
  ...
}

, die eine umhüllte Instanz des ursprünglichen Objekts kehrt mit nur den Namen geändert und alle andere Eigenschaft liest und Methodenaufrufe auf das ursprüngliche Objekt weitergeleitet werden.

Wie eine generische Wrapper-Klasse für diese erhalten, ohne dass es für alles INameable Umsetzung Typen zu implementieren? Glauben Sie, dass das möglich ist?

War es hilfreich?

Lösung

Nein, das ist nicht möglich, es sei denn, T eingeschränkt ist eine Schnittstelle zu sein oder eine Klasse mit allen Mitgliedern virtuell, und diese Einschränkung ist nicht möglich zu sein, bei der Kompilierung angeben (wenn Sie eine Laufzeitprüfung schreiben könnten, wenn Sie sind glücklich, mit diesem Ansatz).

Der Grund, warum Sie es nicht für beliebige Arten tun können, ist, dass, wenn Sie ein Objekt vom Typ T nehmen, dann müssen Sie ein Objekt zurückgeben, die T zuordenbar ist. Wenn ich ein Objekt übergeben, die wie folgt aussieht ...

public sealed class SomeClass : INameable
{
    public string Name { get; }
    public string Abc { get; }
}

... dann gibt es keine Möglichkeit, eine andere Art erstellen können, die zuordenbar zu SomeClass ist. Nicht mit Reflection.Emit oder anderen Verfahren, da der Typ abgedichtet ist.

Wenn Sie jedoch sind mit den Einschränkungen glücklich, die ich erwähnt hat, dann könnte man so etwas wie das Schloss Dynamic Rahmen verwenden, um eine Art zu schaffen, die die übergebene Objekt-Proxys und fängt die Anrufe entweder vorwärts oder neu implementieren als angemessen ist.

Andere Tipps

Nun, ja, es ist möglich, aber es beinhaltet Code im Speicher zu erzeugen.

Sie können sehen Reflection.Emit und hier .

Beachten Sie, dass es eine Menge Code beinhalten wird.

Das heißt, wenn ich nehme an, ich verstehe Sie richtig.

Hier ist, was ich denke, Sie fragen nach:

SomeNameableObject a1 = new SomeNameableObject("ThisIsTheFirstName");
SomeNameableObject a2 = a1.Rename("ThisIsTheSecondName");
// a1 works, still has the name ThisIsTheFirstName
// a2 works, but everything is routed to a1,
//    except for the name, which is ThisIsTheSecondName

Ist das richtig?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top