【问题标题】:C# Polymorphism: Getting a derived class' property instead of base class' field of the same nameC#多态性:获取派生类的属性而不是基类的同名字段
【发布时间】:2014-04-13 01:26:02
【问题描述】:

我有一个基类 Ref:

public class Ref<T>
    {
        public T Value;

        public Ref() { }

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

还有一个派生类 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;
        }
    }

然后我声明一个 Ref 并将其初始化为 RefProperty(多态性):

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

getIntDoubled 和 setIntDoubled 是预期的方法:

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

其中 myInt 是声明的测试整数:

int myInt = 10;

然后我打印:

Console.WriteLine(IntDoubled.Value);

我希望它会返回 20,因为派生类 IntDoubled 中名为 Value 的属性调用了返回 myInt*2 的 getIntDoubled() 方法。 但由于 IntDoubled 被声明为 Ref 而不是 RefProperty,因此它返回基类的 Value 字段(由于未设置值,因此返回 0)。

所以问题是:如果实例是多态的,如何获得派生类的属性而不是基类的同名字段?

【问题讨论】:

  • 为什么在基类和子类中都有Value的定义?您使用它的方式,它应该在基类中是抽象的,以强制它在子类中定义。
  • spender 在下面的回答是一个更好的解决方案,但您也可以在获得Value 之前将IntDoubled 转换为RefProperty,例如Console.WriteLine(((RefProperty)IntDoubled).Value);
  • 编译代码时编译器给出了哪些警告?

标签: c# properties polymorphism field derived


【解决方案1】:

您的基类和子类之间的一致性如何? You shouldn't be exposing fields publicly 无论如何,因此在基类中创建 Value 作为自动道具非常有意义。现在您可以将其设为虚拟并轻松覆盖它。完全消除任何字段/属性混淆。

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

【讨论】:

  • 我想避免为 Ref 使用属性,因为我无法编辑属性的变量(仅将属性作为一个整体).. 也将属性用于没有额外 get 的变量/set 逻辑是我想避免的事情..
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 2017-11-05
  • 2022-01-08
  • 2015-06-25
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
相关资源
最近更新 更多