【问题标题】:Is it possible to add an accessor to a property in .NET by overriding it?是否可以通过覆盖将访问器添加到 .NET 中的属性?
【发布时间】:2009-02-13 11:03:37
【问题描述】:

有可能做这样的事情吗?

class A
{
    public virtual string prop
    {
        get
        {
            return "A";
        }
    }
}
class B: A
{
    private string X;
    public override string prop
    {
        get
        {
            return X;
        }
        set
        {
            X = value;
        }
    }
}

也就是说,基类提供了一个只有 GET 访问器的虚拟属性,但子类覆盖了 GET 并且还提供了一个 SET。

当前示例无法编译,但也许我在这里遗漏了一些东西。

补充:澄清一下,不,我不想用 new 重新定义。我想添加一个新的访问器。我知道它不在基类中,所以它不能被覆盖。好的,让我试着解释一下没有语法糖的情况:

class A
{
    public virtual string get_prop()
    {
            return "A";
    }
}
class B: A
{
    private string X;
    public override string get_prop()
    {
        return X;
    }
    public virtual string set_prop()
    {
        X = value;
    }
}

【问题讨论】:

  • 重新编辑 - 简单的答案是否定的:你不能。
  • 在您的答案中编辑此内容,我会接受。 :)

标签: .net properties polymorphism overriding accessor


【解决方案1】:

不,这是不可能的。不幸的是,您甚至无法覆盖和更改访问器级别(例如,从 protectedpublic),如 MSDN 中所述。我建议您考虑稍微重构代码/类,并寻找一种替代方法来完成此任务,例如使用派生类中的 SetProperty 方法使用 protected 修饰符声明 set 访问器。

【讨论】:

    【解决方案2】:

    不,没有办法做到这一点。想想你的虚拟属性的语法糖是如何被处理的,即它被转换为:

    public virtual string get_prop();
    

    没有可覆盖的 set_Prop 方法,也不能覆盖不存在的方法。

    【讨论】:

    • 不确定您的意思,但您可以添加一个虚拟方法作为“set”属性,该属性将转换为虚拟 set 方法...
    【解决方案3】:

    您可以通过在派生类中使用“new”关键字来隐藏基类实现。以下应该编译成功:

    class A
    {
        public virtual string prop
        {
            get
            {
                return "A";
            }
        }
    }
    class B : A
    {
        private string X;
        public new string prop
        {
            get
            {
                return X;
            }
            set
            {
                X = value;
            }
        }
    }
    

    【讨论】:

    • 引入不同的支持字段通常是有风险的,但是......从黑盒的角度来看,A 类可能有一个字段等作为底层实现,并且对该字段的任何使用都是值得怀疑的。 ..
    【解决方案4】:

    引入一个新领域有点混乱。无论哪种方式,您都需要小心不要破坏多态性和继承(如果基类与私有字段对话怎么办?)。

    关于在覆盖时添加新的访问器;简单的答案是“不,你不能”。当您覆盖时,您只能影响现有的访问器,因为这是在成员的虚拟表中定义的(被覆盖的成员仍然由基/声明类“拥有”,而不是覆盖类)。

    一个选项(不理想)是重新声明该属性,但您仍然需要一种方法来与基类对话。所以如果基类中的访问器是protected:

    class A
    {
        public string prop
        {
            get;
            protected set;
        }
    }
    class B : A
    {
        public new string prop
        {
            get { return base.prop; }
            set { base.prop = value; }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      相关资源
      最近更新 更多