0

I have a base class Ref<>:

public class Ref<T>
    {
        public T Value;

        public Ref() { }

        public Ref(T initialValue)
        {
            Value = initialValue;
        }
    }

and a derived class RefProperty<>:

public class RefProperty<T> : Ref<T>
    {
        public Func<T> Getter;
        public Action<T> Setter;

        public T Value
        {
            get { return Getter(); }
            set { Setter(value); }
        }

        public RefProperty(Func<T> getter, Action<T> setter)
        {
            Getter = getter;
            Setter = setter;
        }
    }

I then declare a Ref and initialize it as a RefProperty (polymorphism):

Ref<int> IntDoubled = new RefProperty<int>(getIntDoubled, setIntDoubled);

Where getIntDoubled and setIntDoubled are methods as expected:

private int getIntDoubled()
        { return myInt * 2; }
private void setIntDoubled(int value)
        { myInt = value / 2; } 

and where myInt is a declared test integer:

int myInt = 10;

I then print:

Console.WriteLine(IntDoubled.Value);

I hope it would return 20 since the property called Value in the derived class, IntDoubled, calls the getIntDoubled() method which returns myInt*2. But since IntDoubled is declared as a Ref and not a RefProperty, it returns the Value field of the base class instead (which returns 0 as the value is not set).

So the question is: How can I get a derived class' property instead of a base class' field of the same name if the instance is polymorphed?

user2345317
  • 117
  • 2
  • 10
  • Why do you have the definition of `Value` in both base and sub-class? The way you are using it, it should be abstract in the base, to force it to be defined in the sub-class. – Daniel Gabriel Apr 13 '14 at 01:49
  • 1
    spender's answer below is a much better solution, but you can also cast `IntDoubled` to `RefProperty` before getting `Value`, like `Console.WriteLine(((RefProperty)IntDoubled).Value);` – Brian Snow Apr 13 '14 at 02:04
  • What warnings was the compiler giving when you compiled your code? – Paulo Morgado Apr 13 '14 at 22:38

1 Answers1

4

How about a bit of consistency between your base and sub-classes? You shouldn't be exposing fields publicly anyway, so it makes a lot of sense to create Value as an auto-prop in the base class. Now you can make it virtual and override it with ease. Any field/property confusion is eliminated completely.

public class Ref<T>
{
    public virtual T Value{get;set;}

    public Ref() { }

    public Ref(T initialValue)
    {
        Value = initialValue;
    }
}



public class RefProperty<T> : Ref<T>
{
    public Func<T> Getter;
    public Action<T> Setter;

    public override T Value
    {
        get { return Getter(); }
        set { Setter(value); }
    }

    public RefProperty(Func<T> getter, Action<T> setter)
    {
        Getter = getter;
        Setter = setter;
    }
}
Community
  • 1
  • 1
spender
  • 117,338
  • 33
  • 229
  • 351
  • I wanted to avoid using a property for Ref since I can't edit a property's variables (only the property as a whole).. Also using a property for a variable with no additional get/set logic is something I'd like to avoid.. – user2345317 Apr 20 '14 at 01:27