it-swarm.com.de

Wie füge ich einem Objekt, das du nicht ändern kannst, eine Eigenschaft hinzu?

Angenommen, ich verwende eine Bibliothek und möchte einer vorhandenen Klasse eine Eigenschaft hinzufügen, die nicht vorhanden ist. In diesem Fall möchte ich Farbe als Eigenschaft von Fruit hinzufügen.

namespace Library
{
    public class Fruit : System.IDisposable
    {
        public string Name { get; set; }

        public void Dispose() { }
    }
}

Gibt es eine Möglichkeit, dies in C # zu tun?


Beispiel, das nicht funktioniert

Mein erster Gedanke war Teilklassen, aber das würde erfordern, dass beide Klassen das Wort teilweise in sich haben. Das ist also nicht machbar.

namespace Library
{
    public partial class Fruit
    {
        public Color Color { get; set; }
    }
}

Das scheint schrecklich

Ich könnte Fruit erben und eine MyFruit-Klasse erstellen. Das scheint mir klobig. Ich würde viel lieber Person.Fruits.FirstOrDefault (). Color aufrufen, als ein MyPerson-Objekt erstellen zu müssen, das von Person erbt, und dann MyPerson.MyFruits.FirstOrDefault (). Color aufzurufen.

namespace Library
{
    public class MyFruit : Fruit
    {
        public Color Color { get; set; }
    }
}

namespace Library
{
    public class MyPerson : Person
    {
        public MyFruit MyFruit { get; set; }
    }
}
7
MiniRagnarok

Die beste Antwort ist, dass Sie nicht sollten. Aber wenn Ihnen ein Leistungsaufwand nichts ausmacht, können Sie mit ConditionalWeakTable<,> Ähnliches tun:

public static class ExtraFruitProperties
{
    private static readonly ConditionalWeakTable<Fruit, Color> _colors = new ConditionalWeakTable<Fruit, Color>();

    public static void SetColor(this Fruit @this, Color color) 
    {
         _colors.Remove(@this);
         _colors.Add(@this, color);
    }

    public static Color GetColor(this Fruit @this) 
    {
         Color color;
         if(_colors.TryGetValue(@this, out color)) return color;
         return default(Color);
    }
}
11
afeygin

Sie nicht.

Der nächstgelegene Punkt ist Java Stileigenschaften über Erweiterungsmethoden. Wenn Sie die Farbe jedoch tatsächlich speichern müssen (anstatt sie in der Funktion zuzuordnen), kann es schwierig sein, sie korrekt auszuführen Die Erweiterungsklasse würde Verweise auf die tatsächliche Klasse enthalten, wenn Sie dies auf naive Weise tun.

Die Alternative besteht darin, die bereits erwähnte Klasse durch Standardvererbung oder -komposition zu erweitern.

1
Telastyn

Verwenden Sie eine separate Hash-Tabelle, um Objekten, die Sie nicht steuern, Eigenschaften hinzuzufügen, und verwenden Sie Ihre eigenen Zugriffsfunktionen, um das gewünschte Verhalten in Bezug auf Ihre hinzugefügten Eigenschaften einheitlich zu gestalten.

Wenn die Speicherbereinigung wahrscheinlich ein Problem darstellt (Ihre auf diese Weise implementierten zusätzlichen Eigenschaften verhindern, dass das Objekt durch Speicherbereinigung erfasst wird), ist dies möglicherweise die nur gute Verwendung schwacher EQ-Hash-Tabellen.

1
ddyer

Ich sehe nicht, was an Ihrer letzten Lösung so "schrecklich" ist. Sie erhalten eine Definition einer Frucht, möchten jedoch, dass diese aussagekräftiger ist. Sie definieren also eine Erweiterung der ursprünglichen Definition mit Ihrem Farbzusatz.

Wirklich, warum bevorzugen Sie:

    Person.Fruits.FirstOrDefault().Color 

über:

    MyPerson.MyFruits.FirstOrDefault().Color

Der einzige Unterschied ist das rein kosmetische Präfix "Mein". Sie könnten auch einen aussagekräftigeren Namen wie ColoredFruit haben.

0
Gabe Noblesmith