¿Cómo agregar una propiedad a un objeto que no puede cambiar?

7

Digamos que estoy usando una biblioteca y me gustaría agregar una propiedad que no existe a una clase existente. En este caso, me gustaría agregar Color como propiedad de Fruit.

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

        public void Dispose() { }
    }
}

¿Hay alguna forma de hacerlo en C #?

Ejemplo que no funcionará

Mi primer pensamiento fue de clases parciales, pero eso requeriría que ambas clases tuvieran la palabra parcial en ellas. Así que eso no es factible.

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

Esto parece horrible

Podría heredar Fruit y crear una clase MyFruit. Esto me parece torpe. Prefiero llamar a Person.Fruits.FirstOrDefault (). Color que tener que crear un objeto MyPerson que se hereda de Person y luego llamar a 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; }
    }
}
    
pregunta MiniRagnarok 01.05.2015 - 17:23

4 respuestas

11

La mejor respuesta es que no deberías. Pero si no te importa una sobrecarga de rendimiento, puedes hacer algo similar 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);
    }
}
    
respondido por el afeygin 01.05.2015 - 17:59
1

No.

Lo más cercano a lo que puede llegar es a las propiedades de estilo Java a través de los métodos de extensión, aunque si realmente necesita almacenar el color (en lugar de asignarlo a la función), puede ser difícil hacerlo correctamente, ya que la clase de extensión tendría referencias. a la clase real si lo haces de forma ingenua.

La alternativa es usar herencia estándar o composición para extender la clase, que ya mencionaste.

    
respondido por el Telastyn 01.05.2015 - 17:29
1

Use una tabla hash separada para agregar propiedades a los objetos que no controla y use Tus propias funciones de acceso para envolver cualquier comportamiento que quieras que parezca uniforme. con respecto a sus propiedades añadidas.

Si es probable que la recolección de basura sea una preocupación (sus propiedades adicionales implementadas de esta manera evitará que el objeto se recoja de basura) este es quizás el solo buen uso de las tablas hash de eq débiles.

    
respondido por el ddyer 01.05.2015 - 19:11
0

No veo por qué es tan "horrible" tu última solución. Te dan una definición de una fruta, pero quieres que sea más descriptiva. Así que define una extensión de la definición original con su adición de Color.

Realmente, ¿por qué prefieres:

    Person.Fruits.FirstOrDefault().Color 

sobre:

    MyPerson.MyFruits.FirstOrDefault().Color

La única diferencia es el prefijo 'Mi' que es puramente cosmético. También podría tener un nombre más descriptivo como ColoredFruit.

    
respondido por el Gabe Noblesmith 01.05.2015 - 19:26

Lea otras preguntas en las etiquetas