微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

返回基础知识 – C#编译器错误

public class BaseClass 
{
  protected void BaseMethod() 
  { 

  }
}

public class DerivedClass : BaseClass 
{
  public void test() 
  {
    DerivedClass d1 = new DerivedClass();
    d1.BaseMethod(); // No error here.        

    BaseClass b1 = new DerivedClass();
    b1.BaseMethod(); // I get compile-time error for this. Why ? 
  }
}

在上面的代码(在VS2005上编译),我得到以下编译时错误

Error 1 Cannot access protected member
‘BaseClass.BaseMethod()’ via a
qualifier of type ‘BaseClass’; the
qualifier must be of type
‘DerivedClass’ (or derived from it)

有人可以解释这种行为吗?这里有些根本错误

解决方法

Eric Lippert刚刚 blogged on this very topic.

它的基本要点是确保一个类可以“信任”受保护方法调用者.共享一个公共基类的类 – 即使该公共基类定义了受保护的方法在这方面基本上是陌生的.

Eric的例子基于银行应用程序的想法.而不是重新创建他的例子,我只会在这里反刍:

// Good.dll:

public abstract class BankAccount
{
  abstract protected void DoTransfer(
    BankAccount destinationAccount,User authorizedUser,decimal amount);
}
public abstract class SecureBankAccount : BankAccount
{
  protected readonly int accountNumber;
  public SecureBankAccount(int accountNumber)
  {
    this.accountNumber = accountNumber;
  }
  public void Transfer(
    BankAccount destinationAccount,decimal amount)
  {
    if (!Authorized(user,accountNumber)) throw something;
    this.DoTransfer(destinationAccount,user,amount);
  }
}
public sealed class SwissBankAccount : SecureBankAccount
{
  public SwissBankAccount(int accountNumber) : base(accountNumber) {}
  override protected void DoTransfer(
    BankAccount destinationAccount,decimal amount)
  {
    // Code to transfer money from a Swiss bank account here.
    // This code can assume that authorizedUser is authorized.
    // We are guaranteed this because SwissBankAccount is sealed,and
    // all callers must go through public version of Transfer from base
    // class SecureBankAccount.
  }
}
// Evil.exe:
class HostileBankAccount : BankAccount
{
  override protected void Transfer(
    BankAccount destinationAccount,decimal amount) {  }
  public static void Main()
  {
    User drEvil = new User("Dr. Evil");
    BankAccount yours = new SwissBankAccount(1234567);
    BankAccount mine = new SwissBankAccount(66666666);
    yours.DoTransfer(mine,drEvil,1000000.00m); // compilation error
    // You don't have the right to access the protected member of
    // SwissBankAccount just because you are in a
    // type derived from BankAccount.
  }
}

虽然你提出的东西看起来很简单,如果它被允许发生,那么你在这里看到的那种恶作剧是可能的.现在您知道受保护的方法调用要么来自您的类型(您可以控制),要么来自您直接继承的类(您在编译时知道).如果它对从继承声明类型继承的任何人开放,那么你将无法确定知道可以调用受保护方法的类型.

当您将BaseClass变量初始化为您自己的类的实例时,编译器只会看到该变量的类型为BaseClass,使您置于信任圈之外.编译器不会分析所有分配调用(或潜在的分配调用)以确定它是否“安全”.

原文地址:https://www.jb51.cc/csharp/97457.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐