【问题标题】:Protected method inheritance in C#C#中受保护的方法继承
【发布时间】:2020-09-09 18:22:03
【问题描述】:

在阅读有关受保护的访问修饰符的文档后,我编写了一个简单的 C# 代码,但我收到了很多不合逻辑的错误。我找不到任何解决方案。

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();
    }
}

我收到以下错误:

prog.cs(19,27):错误 CS0621:SMGController.Shoot()': virtual or abstract members cannot be private prog.cs(19,27): error CS0507: SMGController.Shoot()':无法更改访问修饰符时 覆盖protected' inherited memberWeaponController.Shoot()' prog.cs(10,25):(与先前错误相关的符号位置) 编译失败:2 个错误,0 个警告

如果我将 SMGController 中的 Shoot() 方法的访问修饰符更改为受保护,我会收到更多错误:

prog.cs(30,8):错误 CS1540:无法访问受保护的成员 WeaponController.Shoot()' via a qualifier of typeSMGController'。 限定符的类型必须为 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()' 是 由于其保护级别 prog.cs(10,25) 无法访问:(位置 与先前错误相关的符号)prog.cs(31,8):错误CS1540: 无法访问受保护成员 WeaponController.Reload()' via a qualifier of typeSMGController'。限定符必须是类型 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()' 由于受到保护而无法访问 level prog.cs(5,17): (符号位置与上一个相关 error) 编译失败:4 个错误,0 个警告

我的代码有什么问题?

【问题讨论】:

  • 您无法从Test 访问ReloadShoot,因为它们是protected。你不明白什么?
  • 受保护的成员可以在其类中访问,也可以通过派生类实例访问。
  • @Владимир 是的,Test 不是派生类。
  • protected internal virtual void Shoot() {...},注意internal 让方法从继承的类或从声明的方法(您的情况)的程序集中调用。见docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/…

标签: c# oop inheritance protected


【解决方案1】:

您不能从类外部调用protected 方法,即从Test 调用WeaponController.Shoot

另外,如果你重写 protected 方法,它也必须是 protected

显然,您希望ReloadShoot 成为public,因此您可以从Test.Main 调用它们。

【讨论】:

  • 由于这个原因:link 受保护的成员可以在其类中和派生类实例中访问。 那么为什么要测试,作为继承类的实例不能调用他的方法呢?
  • Test 不继承自 SMGController 或 WeaponController。为此,您必须将其声明为 public class Test : SMGController
【解决方案2】:

protected 修饰符意味着只有类本身或子类可以访问Shoot

您正在尝试从与SMGControllerWeaponController 都没有继承关系的其他类Test 访问它,并且protected 修饰符禁止此类访问。

参考见https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/protected,尤其是第一节的这一行:

受保护的成员可以在其类中访问,也可以通过派生类实例访问。

您可以通过设置Shoot public 来解决此问题。或者,如果您坚持保留它protected,那么您需要添加一个方法,例如public PublicShoot() 然后调用受保护的方法。

【讨论】:

  • 那么为什么 test 作为 SMGController 的一个实例不能调用它的方法呢?
  • public class Test 没有明确指定继承,这意味着它继承自类 Object
猜你喜欢
  • 2015-03-26
  • 2016-03-17
  • 2010-11-17
  • 2016-09-04
  • 2010-09-14
  • 2016-09-04
  • 2016-06-12
  • 2014-06-09
  • 2019-02-10
相关资源
最近更新 更多