【问题标题】:C# Inheritance: Static vs. Non-Static FieldC# 继承:静态与非静态字段
【发布时间】:2011-10-11 21:26:55
【问题描述】:

我有一个库基类 (Controller) 和三个继承自 Controller 的子类(SensorOutputEnvironment),其中:

public class Controller
{
   private SerialPort serial;
   private Sensor sensorSettings;
   private Output outputSettings;
   private Environment environmentSettings;       


   protected Dictionary<int, string> ErrorDescriptions
   { get{ this.errorDescriptions; } }

   protected SerialPort ControllerSerialPort
   { get{ this.serial; } }

   protected Sensor SensorSettings
   { get{ this.sensorSettings; } }

   // The other sub-class get properties.

   protected string SendReceive(string controllerCommand)
   { ... }

   ...
 }

 public class Sensor : Controller {...}
 ... // Other sub-classes

我的问题是:我应该将errorDescriptions 设为静态吗?这些错误描述不会因控制器而异(即静态),但我不确定在继承的类中会发生什么。我必须在Sensor 类中将它们称为Sensor.errorDescription,还是仍然是Controller.errorDescription

编辑

哇,我刚刚意识到我搞砸了。我认为应该是这样的:

private abstract class ControllerBasics
{
   protected SerialPort serial;  // The serial port to communicate with the controller.
   protected Dictionary<int, string> errorDescriptions = new Dictionary<int, string> {...};   // Possible errors for the controller (known and fixed). Won't change from controller to controller.
   public enum Sensors {One, Two, ...};   // Possible sensor selection.

   public string SendReceiveCommand(string command){...} // Method to send string command over "serial".       
}

public class OverallController : ControllerBasics // The controller class.
{       
   // Add top-level controller settings.
   private string controllerName = "Controller1"; // Have a property to get/set.
   private bool controllerON; // Controller on/off. Have property to get/set.
   ... // Other similar fields and methods.

   // Used to "sort" the controller's many settings/functions.
   private SensorSettings sensorSettings;  // Have get/set properties for these so I could do the following: overallControllerInstance.GetSensorSettingsProperty.SetActiveSensorCount(5);
   private OutputSettings outputSettings;
   private EnvironmentSettings environmentSettings;

   public OverallController(string name, string comPort, ...)  // Constructor.
   {
      // Basic settings initialization.
      // Create serial port.
      this.sensorSettings = new SensorSettings(this.serial);
      this.outputSettings = ...
}

public class SensorSettings : ControllerBasics // Class to hold the controller's specific sensor settings and their respective get/set methods. Not a new type of controller.
{
   private int activeSensorCount; // Have public method to get/set.
   ... // Others.

  public void SetActiveSensorCount(int sensorCount)
  {
     // Send command using inherited SendReceive().
  }
  ... // Others.
}

public class OutputSettings : ControllerBasics   // Same logic as SensorSettings.
{
   private string units; // Have public method to get/set.
   ... // Others.

  public string GetUnitType()  // Meters, mm, um...
  {
     // Send command using inherited SendReceive().
  }
  ... // Others.
}

public class EnvironmentSettings : ControllerBasics   // Same logic as SensorSettings.
{
   ...
}

因此,如果在 ControllerBasics 中定义的 errorDescriptions 是已知且固定的(并且在所有派生类中都需要),我应该将其设为静态还是应该将其保留为受保护并且每个派生类都有自己的字典(即 this.错误描述)?

【问题讨论】:

  • 如果您打算这样做,请不要直接访问字典,而是添加一些使用静态锁的静态方法,以确保线程安全。
  • @Groo,是的,但只有当字典没有完全填充到基本静态初始化程序中时,才需要锁定。 (听起来可能是这样)
  • @Jon,您的问题目前不太可能引起良好的新反应。由于您第一次写错了问题,我建议您提交一个按照您的意图写的新问题,这没有错。您甚至可能想要撤消对此问题的编辑,并将其留给您的新问题。 (我只是想帮助你让你的问题合法地吸引更多的眼球)
  • @KirkWoll:谢谢,我试试看。

标签: c# inheritance static


【解决方案1】:

只有 一个 静态变量,不管你有多少子类。它是否意味着因子类而异,还是真正是一个全局映射?如果是后者,那么静态变量是合适的。如果不是......好吧,有多种选择,但您需要告诉我们您使用地图的目的。

【讨论】:

  • 我更新了原帖,之前完全错了。只有一个控制器,所以我使用继承基本上共享控制器的串行端口和所有控制器串行命令所需的其他非常基本的方法/字段。我希望这是有道理的......
【解决方案2】:

如果您只需要字典的一个实例而不是需要,请将其更改为受保护的静态。此外,您应该使用ConcurrentDictionary 代替线程安全。

在派生类中,您可以使用Controller.errorDescription 访问该字段

【讨论】:

  • 感谢您的帮助,我更新了我的原始帖子(我第一次弄错了),现在它在一个抽象类中。那会有什么不同吗?
  • 您是否希望每个控制器实例共享同一个字典?我们无法回答。但是如果你这样做了,你应该使用 ConcurrentDictionary,因为它是线程安全的。
【解决方案3】:

好吧,您的派生类将看不到私有成员。为此,您需要一个受保护的成员或属性。在类中,您可以将其称为 errorDescriptions 或 this.errorDescriptions。

我会非常警惕有一个静态的、受保护的成员变量,它不是线程安全的,并且可以被派生类改变。那只是自找麻烦。

【讨论】:

  • 除非你同步它们,否则是的。请参阅msdn.microsoft.com/en-us/library/xfhwa508.aspx 并滚动到“线程安全”部分。如果您只有多个阅读器,您是安全的,但对于多个阅读器和编写器,您需要同步或使用 ConcurrentDictionary。
  • 是的,除非你有多个编写者,否则你是安全的,所以“只有公共静态字典是线程安全的”这句话充其量是令人困惑的。因为 1)“公开”是无关紧要的 2)“静态”是无关紧要的 3)如果你写它不是线程安全的
  • 啊,对。我将“成员”误读为“实例”。我会纠正头脑放屁。
猜你喜欢
  • 2011-04-02
  • 2013-10-20
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
相关资源
最近更新 更多