【问题标题】:Initializing Base Class: declaring a variable twice?初始化基类:两次声明一个变量?
【发布时间】:2018-09-12 08:19:31
【问题描述】:

我目前正在阅读 C# 教程。现在我遇到了这个:

using System;

namespace RectangleApplication {
   class Rectangle {

      //member variables
      protected double length;
      protected double width;

      public Rectangle(double l, double w) {
         length = l;
         width = w;
      }
      public double GetArea() {
         return length * width;
      }
      public void Display() {
         Console.WriteLine("Length: {0}", length);
         Console.WriteLine("Width: {0}", width);
         Console.WriteLine("Area: {0}", GetArea());
      }
   }//end class Rectangle  
   class Tabletop : Rectangle {
      private double cost;
      public Tabletop(double l, double w) : base(l, w) { }

      public double GetCost() {
         double cost;
         cost = GetArea() * 70;
         return cost;
      }
      public void Display() {
         base.Display();
         Console.WriteLine("Cost: {0}", GetCost());
      }
   }
   class ExecuteRectangle {
      static void Main(string[] args) {
         Tabletop t = new Tabletop(4.5, 7.5);
         t.Display();
         Console.ReadLine();
      }
   }
}

class Tabletop 中有两次声明cost。一次为private double cost;,4 行后为double cost;

为什么会这样?

删除double cost; 时,代码仍然有效。当double cost 在代码中时,我可以将鼠标悬停在private double cost; 上并阅读消息:Tabletop.cost 字段从未使用过”。我几乎可以消除任何一个成本,并且代码工作正常。

  1. 他们是否忘记删除其中一个声明或背后有什么原因?
  2. 另外,为什么我没有收到“成本已定义”之类的错误消息?

这里是Tutorial link

【问题讨论】:

  • 投票(+1)因为他们忘记删除它。两者都不重要,本来可以写return GetArea() * 70;
  • 您的方法的成本会在您的班级中隐藏同名的成员。因此,您在方法中有效地使用了方法cost,而在方法之外您可以访问该字段。这就是为什么当我打算使用字段而不是方法的值时,我更喜欢添加(冗余)this-qualifier。
  • 您没有收到错误消息,因为它们在不同的范围内。
  • 删除局部变量是必要的修复。当你放回去时,字段成本将始终保持为 0。可通过 Display() 观察。

标签: c# class inheritance declare


【解决方案1】:

private double cost; 未使用,可以删除。

您不会收到错误,因为正如 John 在 cmets 中所说,它在不同的范围内;一个被定义为类的字段,而另一个是局部变量。当使用cost 时,访问的是局部变量。要访问该字段,可以使用this.cost

class A
{
  private int a = 1;

  void A()
  {
    int a = 2;

    Console.WriteLine(a); // 2
    Console.WriteLine(this.a); // 1
  }
}

请注意,您不能有多个同名的局部变量,即使在不同的范围内:

void A()
{
  int a = 1;

  if(someCondition)
  {
    int b = 2; // Compiler error: A local variable named 'a' cannot be declared in this scope because it would give a different meaning to 'a', which is already used in a 'parent or current' scope to denote something else
  }
}

【讨论】:

    【解决方案2】:

    实际上,在您的类Tabletop 中,作用域cost 是重叠的,因为在方法GetCost 中还有一个名为cost 的局部变量。

    GetCost 的范围内,当您引用cost 时,您实际上指的是名为cost 的本地范围对象,而不是外部范围内的对象(类中的对象)。发生这种情况时,在外部作用域中声明的cost 被内部作用域隐藏(在方法中)。

    【讨论】:

      【解决方案3】:

      在成员范围内(在您的情况下是在方法中)定义与现有成员同名的变量时,您只需隐藏后者并引用前者。

      所以在你的例子中:

      class Tabletop : Rectangle 
      {
          private double cost;
          public Tabletop(double l, double w) : base(l, w) { }
      
          public double GetCost() 
          {
              double cost;  // this hides the field
              cost = GetArea() * 70;
              return cost;  // this referts to the variable defined two lines above
          }
          public void Display() 
          {
              Console.WriteLine("Cost: {0}", cost); // while this refers to the field
          }
      }
      

      cost from within GetCost 将引用 local 变量,而在 Display 中使用 cost 例如将引用 字段

      这绝对没问题。然而,它可能会产生混乱,从而产生意想不到的行为。这就是为什么一些开发者倾向于使用this-qualifier:

      public double GetCost() 
      {
          double cost;
          this.cost = GetArea() * 70;
          return this.cost;
      }
      

      使用您引用当前实例的限定符,使this.cost` 可以访问您的字段而不是变量。

      【讨论】:

        【解决方案4】:

        我认为他们确实忘记删除它。

        为什么你没有得到“cost is already defined”错误,这是因为GetCost()中的double cost是本地的(只能在GetCost()方法中访问,并且在GetCost()方法之后会从内存中销毁已完成),而private double cost 可供整个Tabletop 类访问,只要Tabletop 实例存在,就会一直保存在内存中。

        【讨论】:

          【解决方案5】:

          在 Tabletop 类中有两次声明的成本。曾经是私人的 双倍成本;以及 4 行之后的双倍成本;

          private double cost;tableTop 类的成员字段,而其他声明是方法体的本地声明。为什么会出现混乱。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-08-23
            • 2021-10-28
            • 2013-04-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多