【问题标题】:Accessing properties of the base class in a double derived class在双派生类中访问基类的属性
【发布时间】:2014-01-22 17:47:06
【问题描述】:

我在访问双派生类中的基类属性时遇到问题。我在下面提供了一个简单的问题示例。

public class Device
{
   public Device(string status)
   {
      Status = status;
   }

   public string Status { get; set; }

   public void SetStatus(string value)
   {
      Status = value;
   }

   public string GetStatus()
   {
      return Status;
   }
}

public class Light : Device
{
   public Light(string status) : base(status)
   {
   }

   public void SetStatus(string value)
   {
      base.SetStatus(value)
   }

   public string GetStatus()
   {
      return Status;
   }
}

public class ColoredLight : Light
{
   public ColoredLight(string status) : base(status)
   {
   }

   public void SetStatus(string value)
   {
      base.SetStatus(value)
   }

   public string GetStatus()
   {
      return Status;
   }
}

// note: The derived classes also have some properties of their own, of course, 
// but they are not needed to illustrate the problem

我知道基类的 Status 属性肯定会被设置为一个值,但是如果我在 ColoredLight 类中调用 GetStatus 方法,它会返回 null。

如果我将 Light 和 ColoredLight 类中的 GetStatus 函数更改为返回 base.GetStatus(),它确实会返回正确的值。但是,我认为应该可以直接在派生类中访问基类的属性。难道我做错了什么?还是应该这样做?

提前感谢您的帮助。

编辑:[已解决] 我遇到的问题是由于我自己的愚蠢和疏忽,因为我在 Device 和 Light 类中声明了 Status 属性。但是,下面的解决方案提高了我对 C# 中“受保护”、“虚拟”和“覆盖”的使用的理解,所以我将保留这个问题,所以它也可以帮助其他人!

【问题讨论】:

  • 由于您没有覆盖 SetStatus 和 GetStatus 方法,您没有收到该代码的警告吗?
  • 你以前用java编程过吧?这不是问题,但 OOP 通常用 C# 编写的有点不同。 (没有明确命名的 Get 和 Set)
  • 我实际上收到了来自 Resharper 的警告,说我应该使用 new 关键字,但是代码会构建并调用正确的方法,所以我认为这不会导致这里出现问题。虽然你说得对,但我也必须改变它。
  • 首先,感谢您的帮助。但正如我在下面提到的,我认为我过于简化了代码,因为我的实际方法返回特定于派生类或基类之一的属性值,具体取决于参数的值。所以实际方法在不同的类中有所不同。此外,这些方法在返回之前还做了一些其他工作,所以我不能只使用可公开访问的属性。我的问题基本上归结为:为什么在派生类中Status的值是null,而它肯定是在基类中设置的?

标签: c# properties base derived


【解决方案1】:

完全摆脱 GetStatus() 和 SetStatus() 方法,这不是 java。而是创建属性 virtual 并根据需要在后代类中覆盖它。

public class Device
{
    public Device(string status)
    {
        this._status = status;
    }

    protected _status;
    public virtual string Status 
    { 
        get
        {
            return _status;
        }
        set
        {
            _status = value;
        }
    }
}

public class Light : Device
{
    public Light(string status) : base(status)
    {
    }
}

public class ColoredLight : Light
{
    public ColoredLight(string status) : base(status)
    {
    }

    public override string Status 
    { 
        get
        {
            return _status;
        }
        set
        {
            _status = value;
        }
    }
}

【讨论】:

  • 其实我可能把问题简单化了。 GetStatus() 方法只是一个示例。我使用的实际方法稍微复杂一些,并且取决于参数的值,要么返回特定于派生类的值,要么返回来自基类之一的值。我现在已经使用声明为virtualoverride 的方法进行了尝试,但这并没有什么区别。出于某种原因,我无法直接从派生类中的基类访问属性。我只能通过一些base.GetProperty() 方法访问它们。
  • 好的,我认为我的确切问题实际上完全是由其他原因引起的。主要是我的愚蠢,因为我不小心在 Device 类和 Light 类中定义了 Status,直到我将代码更改为您的解决方案时才看到它。您提供的protectedvirtualoverride 上的示例确实对我有很大帮助,尽管我了解了如何使我的代码变得更好!所以谢谢你!
猜你喜欢
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
  • 2017-03-28
相关资源
最近更新 更多