简体   繁体   中英

C# Polymorphism: Getting a derived class' property instead of base class' field of the same name

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?

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM