Come aggiungere una proprietà a un oggetto che non è possibile modificare?

7

Diciamo che sto usando una libreria e vorrei aggiungere una proprietà che non esiste in una classe esistente. In questo caso, vorrei aggiungere Colore come proprietà di Fruit.

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

        public void Dispose() { }
    }
}

C'è un modo per farlo in C #?

Esempio che non funzionerà

Il mio primo pensiero era di classi parziali, ma ciò richiederebbe che entrambe le classi avessero la parola parziale in esse. Quindi non è fattibile.

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

Sembra orribile

Potrei ereditare Fruit e creare una classe MyFruit. Questo mi sembra schifoso. Preferisco chiamare Person.Fruits.FirstOrDefault (). Color piuttosto che dover creare un oggetto MyPerson che eredita da Person e quindi chiamare MyPerson.MyFruits.FirstOrDefault (). Color.

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

namespace Library
{
    public class MyPerson : Person
    {
        public MyFruit MyFruit { get; set; }
    }
}
    
posta MiniRagnarok 01.05.2015 - 17:23
fonte

4 risposte

11

La migliore risposta è che non dovresti. Ma se non ti preoccupa un overhead delle prestazioni, puoi fare qualcosa di simile con ConditionalWeakTable<,> :

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);
    }
}
    
risposta data 01.05.2015 - 17:59
fonte
1

Non lo fai.

Il più vicino possibile è proprietà di stile Java tramite i metodi di estensione, anche se è effettivamente necessario memorizzare il colore (al contrario di mapparlo nella funzione) può essere difficile farlo correttamente poiché la classe di estensione manterrà i riferimenti alla classe reale se lo fai in modo ingenuo.

L'alternativa sta usando l'ereditarietà o la composizione standard per estendere la classe, che hai già menzionato.

    
risposta data 01.05.2015 - 17:29
fonte
1

Utilizzare una tabella hash separata per aggiungere proprietà agli oggetti che non si controllano e utilizzare le tue funzioni di accesso per avvolgere qualsiasi comportamento tu voglia sembrare uniforme rispetto alle tue proprietà aggiunte.

Se è probabile che la garbage collection costituisca un problema (le proprietà extra implementate in questo modo impedirai che l'oggetto venga raccolto dalla spazzatura) questo è forse il solo buon uso delle tabelle hash eq deboli.

    
risposta data 01.05.2015 - 19:11
fonte
0

Non vedo cosa sia "orribile" della tua ultima soluzione. Ti viene data una definizione di un frutto, ma vuoi che sia più descrittivo. Quindi definisci un'estensione della definizione originale con l'aggiunta del colore.

Davvero, perché preferisci:

    Person.Fruits.FirstOrDefault().Color 

sopra:

    MyPerson.MyFruits.FirstOrDefault().Color

L'unica differenza è il prefisso "My" che è puramente cosmetico. Potresti anche avere un nome più descrittivo come ColoredFruit.

    
risposta data 01.05.2015 - 19:26
fonte

Leggi altre domande sui tag