5
votes

I have a protected method in base class :

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

The method is overrided one of the derived classes:

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

Another derived class has an instance of the first derived class.
When I try to access the Foo method (existing in base class, as mentiond) I get an error :

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

The error I get:

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)

I understand that protected members should not give up their value to any other instance, even an instance derived from the same type,
but is there a way not to modify the method as public?

4
If it is acceptable to make it public only within that assembly, you can mark it as internalSuresh Kumar Veluswamy

4 Answers

8
votes

You can make the Foo method declaration as protected internal....

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

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

Here "protected internal" means the member is visible to any class inheriting the base class, whether it's in the same assembly or not. The member is also visible via an object declared of that type anywhere in the same assembly.

0
votes

You can try this it hides the base version of the method and makes the overridden version public.

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

You can use internal access modifier, It will work same as public, but wont work with different assemblies.

More info on MSDN : http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx

So, just replace protected with internal. Hope, it helps you. :)

0
votes

Update: I've just seen that both of the classes are derived from BaseClass. In the initial sample no base class was specified. In this case one way to solve this problem is to create a new AbstractDerived which would be the base class for those 2 classes. Something like this:

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

Old answer: You should have DerivedClass2 derived from Derived1 and use base keyword. You can find more information and examples about base keyword here: http://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx In your case it will look something like this:

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