从派生类访问受保护的方法

时间:2014-03-24 09:50:46

标签: c# override protected

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

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)

我理解受保护的成员不应该将其值放弃到任何其他实例,即使是来自相同类型的实例,
但有没有办法不将方法修改为公开?

4 个答案:

答案 0 :(得分:6)

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

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

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

此处“protected internal”表示该成员对继承基类的任何类都是可见的,无论它是否在同一个程序集中。通过在同一程序集中的任何位置声明该类型的对象,也可以看到该成员。

答案 1 :(得分:0)

您可以尝试这样做,它会隐藏方法的基本版本,并将重写的版本设为公开。

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

答案 2 :(得分:0)

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

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

所以,只需用内部替换protected。 希望,它可以帮助你。 :)

答案 3 :(得分:0)

更新:我刚刚看到这两个类都是从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
   }
}