C# – Adding behaviour to a part of a third party class

Architecturecdesigninheritanceprogramming-languages

I am working with an effectively third-party library. This library has a base class that's used as the interface (C++ style), ComponentBase. ComponentBase has a number of methods and setters that are implemented by its derived classes. In particular, right now I am interested in one specific item there: the Value property (which has a public get and a protected set), effectively an array.

e.g.

public abstract class ComponentBase
{
  // stuff we don't care about
  protected Value m_Value;
  public Value ValueObj { get; protected set; }
}

public class Value
{
  private object[] m_Value;
  public virtual object this[int Index]
    {
    get; set;
    }
} 

I need to add specific behaviour so that something happens when the values inside Value are changed. As can be seen, I'd need to somehow change the get/set implementation.

I fail to see how to do so, however. How can that be accomplished?

Best Answer

I understand you simplified things in order to focus on your issue at hands.

You did well, imo, but left some blanks (in the Value class) I had to fill in, while trying to make as few / little assumptions as possible.

Following just plain, good old OOP principles, here's what you may find useful:

public abstract class ComponentBase
{
    // stuff we don't care about
    protected Value m_Value;

    public Value ValueObj { get; protected set; }
}

public class Value
{
    private object[] m_Value;

    protected Value()
    {
        // totally arbitrary, for sake of demo:
        m_Value = new object[10];
    }

    public virtual object this[int index]
    {
        get { return m_Value[index]; }
        set { m_Value[index] = value; }
    }
}

public class MyComponent : ComponentBase
{
    // (virtual for extensiblity)
    protected virtual Value NewValue()
    {
        return new MyValue();
    }

    public MyComponent()
    {
        ValueObj = NewValue();
    }
}

public class MyValue : Value
{
    // (virtual for semantic refinement)
    protected virtual object GetData(int index)
    {
        var data = base[index];
        // or whatever else needs to happen here:
        Console.WriteLine("{0}: just got {1} at {2}", GetType().Name, data ?? "(null)", index);
        return data;
    }

    // (virtual for semantic refinement)
    protected virtual void SetData(int index, object data)
    {
        base[index] = data;
        // or whatever else needs to happen here:
        Console.WriteLine("{0}: just put {1} at {2}", GetType().Name, data ?? "(null)", index);
    }

    public override object this[int index]
    {
        get { return GetData(index); } set { SetData(index, value); }
    }
}

class Program
{
    public static void Main(string[] args)
    {
        var component = new MyComponent();

        Console.WriteLine("Component prep...");
        component.ValueObj[0] = "Frederic";
        component.ValueObj[1] = "Bastiat";
        component.ValueObj[2] = 1801;
        component.ValueObj[3] = 1850;
        component.ValueObj[4] = "The Law";

        Console.WriteLine("Component use...");
        var book = component.ValueObj[4];
        var first = component.ValueObj[0];
        var last = component.ValueObj[1];
        var born = component.ValueObj[2];
        var rip = component.ValueObj[3];

        Console.WriteLine(@"""{0}"", by {1} {2} ({3} - {4})", book, first, last, born, rip);

        Console.ReadKey();
    }
}

'HTH,