-1

I have a simple C# code written after reading documentation about protected access modifier, but I am recieving a lot of illogical errors. I cant find any solutions to them.

using System;

public class WeaponController
{
    protected void Reload()
    {
        Console.WriteLine("Reload");
    }

    protected virtual void Shoot()
    {

    }
}

public class SMGController : WeaponController
{

    private override void Shoot()
    {
        Console.WriteLine("Shoot");
    }
}

public class Test
{
    public static void Main()
    {
        var test = new SMGController();
        test.Shoot();
        test.Reload();
    }
}

And I am recieving following errors:

prog.cs(19,27): error CS0621: SMGController.Shoot()': virtual or abstract members cannot be private prog.cs(19,27): error CS0507: SMGController.Shoot()': cannot change access modifiers when overriding protected' inherited memberWeaponController.Shoot()' prog.cs(10,25): (Location of the symbol related to previous error) Compilation failed: 2 error(s), 0 warnings

If I will change access modifier of Shoot() method in SMGController to protected I recieve even more errors:

prog.cs(30,8): error CS1540: Cannot access protected member WeaponController.Shoot()' via a qualifier of typeSMGController'. The qualifier must be of type Test' or derived from it prog.cs(10,25): (Location of the symbol related to previous error) prog.cs(30,8): error CS0122:WeaponController.Shoot()' is inaccessible due to its protection level prog.cs(10,25): (Location of the symbol related to previous error) prog.cs(31,8): error CS1540: Cannot access protected member WeaponController.Reload()' via a qualifier of typeSMGController'. The qualifier must be of type Test' or derived from it prog.cs(5,17): (Location of the symbol related to previous error) prog.cs(31,8): error CS0122: WeaponController.Reload()' is inaccessible due to its protection level prog.cs(5,17): (Location of the symbol related to previous error) Compilation failed: 4 error(s), 0 warnings

What is wrong with my code?

  • 4
    You can't access `Reload` or `Shoot` from `Test` because they are `protected`. What don't you understand? – Sweeper May 22 '20 at 20:05
  • A protected member is accessible within its class AND by derived class instances. – Владимир May 22 '20 at 20:08
  • 1
    @Владимир Yes, and `Test` is not a derived class. – juharr May 22 '20 at 20:09
  • `protected internal virtual void Shoot() {...}`, note `internal` let the method be called either from inherited class or from the *assembly* the method declared (your case). See https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/accessibility-levels – Dmitry Bychenko May 22 '20 at 20:23

2 Answers2

3

You can't call protected methods from outside the class, i.e. call WeaponController.Shoot from Test.

Also, if you override a protected method, it has to be protected, too.

Obviously, you want Reload and Shoot to be public, so you can call them from Test.Main.

Haukinger
  • 10,420
  • 2
  • 15
  • 28
  • Due to this: [link](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/protected) _A protected member is accessible within its class and by derived class instances._ So why test, being instance of inherited class cant call his methods? – Владимир May 22 '20 at 20:14
  • Test doesn't inherit from SMGController or WeaponController. To do that, you would have to declare it as `public class Test : SMGController`. – Robert Harvey May 22 '20 at 20:33
1

The protected modifier means that only the class itself or a subclass can access Shoot.

You are trying to access it from some other class Test that has no inheritance relation with both SMGController and WeaponController, and such access is forbidden by the protected modifier.

For reference, see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/protected, especially this line in the first section:

A protected member is accessible within its class and by derived class instances.

You can fix this by making Shoot public. Or if you insist on keeping it protected, then you would need to add a method e.g. public PublicShoot() that then calls the protected method.

Peter B
  • 22,460
  • 5
  • 32
  • 69