【问题标题】:Protected method access from derived class从派生类访问受保护的方法
【发布时间】:2014-05-01 14:25:19
【问题描述】:

我在基类中有一个受保护的方法:

public class BaseClass
{
  protected virtual void Foo(){}
}    

该方法被派生类之一覆盖:

public class Derived1 : BaseClass
{
   protected override void Foo()
    {
     //some code...
    }
}    

另一个派生类具有第一个派生类的实例。
当我尝试访问 Foo 方法(如前所述,存在于基类中)时,出现错误:

 public class DerivedClass2 : BaseClass
    {
     BaseClass instance = new DerivedClass1();
     instance.Foo(); // Here I get an error
    }

我得到的错误:

Error CS1540: Cannot access protected member 'BaseClass.Foo' via a qualifier of type 'BaseClass';   
the qualifier must be of type 'DerivedClass2' (or derived from it)

我了解受保护的成员不应将其价值放弃给任何其他实例,即使是从同一类型派生的实例,
但是有没有办法不将方法修改为public?

【问题讨论】:

  • 如果可以接受只在该程序集中公开,您可以将其标记为内部

标签: c# overriding protected


【解决方案1】:

您可以将 Foo 方法声明设置为受保护的内部......

public class BaseClass
{
  protected internal virtual void Foo(){}
} 

public class Derived1 : BaseClass
{
   protected internal override void Foo()
    {
     //some code...
    }
}

这里的“受保护的内部”意味着该成员对任何继承基类的类都是可见的,无论它是否在同一个程序集中。该成员还可以通过在同一程序集中的任何位置声明为该类型的对象可见。

【讨论】:

  • 他正在使用基类实例访问Foo(),这就是他收到此异常的原因。
  • @Aftab:虽然变量是基类类型,但它持有的实例是派生类型。因此它有效!
  • @SureshKumarVeluswamy,谢谢,它运行良好!您能否添加一些其他解释,以便我能够正确理解内部保护为什么起作用?提前致谢!
【解决方案2】:

你可以试试这个,它隐藏了方法的基本版本,并公开了覆盖的版本。

public class Derived1 : BaseClass
{
    public new void Foo()
    {
        //some code...
    }
}

【讨论】:

  • 谢谢。我的目的是仍然沿继承层次设置受保护的方法。有办法吗?
  • 如果需要从没有继承的类访问,则将基类上的方法公开
【解决方案3】:

您可以使用内部访问修饰符,它与 public 相同,但不能与不同的程序集一起使用。

MSDN 上的更多信息:http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx

所以,只需将 protected 替换为 internal。 希望,它可以帮助你。 :)

【讨论】:

    【解决方案4】:

    更新: 我刚刚看到这两个类都是从 BaseClass 派生的。在初始样本中,没有指定基类。在这种情况下,解决此问题的一种方法是创建一个新的 AbstractDerived ,它将作为这两个类的基类。像这样的:

    public abstract AbstractDevired: BaseClass
    {
       protected override Foo()
       {
          //put implementation from Derived1 here
       }
    }
    
    public Derived1: AbstractDevired
    {
      //no need to override here because it is the same logic in AbstractDerived class
    }
    
    public DerivedClass2: Derived1
    {
       protected override Foo()
       {
          base.Foo();
          //some code here
       }
    }
    

    旧答案: 您应该从 Derived1 派生 DerivedClass2 并使用 base 关键字。您可以在此处找到有关 base 关键字的更多信息和示例:http://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx 在你的情况下,它看起来像这样:

    public class DerivedClass2 : Derived1
    {
       protected override void Foo()
       {
          base.Foo();
          //some code
       }
    }
    

    【讨论】:

    • 但是我不能使用覆盖方法。有任何想法吗?谢谢
    猜你喜欢
    • 2017-12-14
    • 1970-01-01
    • 2011-06-08
    • 2015-12-30
    • 2016-04-07
    • 2016-03-11
    • 2014-08-27
    • 2018-04-17
    • 2019-01-20
    相关资源
    最近更新 更多