C# 继承:静态字段与非静态字段
我有一个库基类 (Controller
) 和三个继承自 Controller
的子类(Sensor
、Output
和 Environment
),其中:
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.errorDescriptions)?
I have a library base class (Controller
) and three sub-classes that inherit from Controller
(Sensor
, Output
, and Environment
) where:
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
My question is this: Should I make the errorDescriptions
static? These error descriptions will not change from controller to controller (i.e. static) but I wasn't sure what happens in the inherited classes. Will I have to refer to them as Sensor.errorDescription
in the Sensor
class or will it still be Controller.errorDescription
?
EDIT
Wow, I just realized I messed up big time. Here's how it should be, I think:
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.
{
...
}
So if errorDescriptions
defined in ControllerBasics
is known and fixed (and required in all derived classes) should I make it static or should I just leave it protected and each derived class will have it's own dictionary (i.e. this.errorDescriptions)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
无论您有多少个子类,都只会有一个静态变量。它是否意味着因子类而异,或者它是真正一个全局映射?如果是后者,那么静态变量就合适了。如果没有……好吧,有多种选择,但您需要告诉我们您使用地图的目的。
There would only be one static variable, however many subclasses you have. Is it meant to vary by subclass, or is it truly one global mapping? If it's the latter, then a static variable is appropriate. If not... well, there are various options, but you'd need to tell us what you're using the map for.
如果您只需要字典的一个实例,请将其更改为受保护的静态。此外,为了线程安全,您应该使用 ConcurrentDictionary 来代替。
在派生类中,您可以使用
Controller.errorDescription
访问该字段If you only need one instance of the dictionary than yes, change it to protected static. Also you should use
ConcurrentDictionary
instead for thread safety.In the derived classes you access the field using
Controller.errorDescription
那么,私有成员对您的派生类不可见。为此,您需要受保护的成员或财产。在类中,您可以将其称为 errorDescriptions 或 this.errorDescriptions。
我会非常警惕有一个静态的、受保护的成员变量,它不是线程安全的,并且可以被派生类改变。那只是自找麻烦。
Well, a private member won't be visible to your derived classes. You would need a protected member or property for that. Within the class, you can just refer to it as errorDescriptions or this.errorDescriptions.
I'd be extremely wary of having a static, protected member variable that isn't thread safe and can be mutated by derived classes. That's just asking for trouble.