public abstract class Variable : INamed<string>
{
private readonly GetValueDelegate getValueDelegate;
private readonly SetValueDelegate setValueDelegate;
private readonly string name;
private readonly VariableContext context;
private readonly int contextKey;
private readonly int number;
private readonly VariableType type;
private readonly Controller controller;
private readonly _PTR_DATA coreIdentifier;
public string Name => name;
public VariableContext Context => context;
public int ContextKey => contextKey;
public int Number => number;
public VariableType ValueType => type;
public object Value
{
get
{
return getValueDelegate(this);
}
set
{
setValueDelegate(this, value);
}
}
internal Controller Controller => controller;
internal _PTR_DATA CoreIdentifier => coreIdentifier;
internal Variable(Controller controller, VariableType type, VariableContext context, int contextKey, int number, string name, GetValueDelegate getValueDelegate, SetValueDelegate setValueDelegate, _PTR_DATA coreIdentifier)
{
this.controller = controller;
this.type = type;
this.context = context;
this.contextKey = contextKey;
this.number = number;
this.name = name;
this.getValueDelegate = getValueDelegate;
this.setValueDelegate = setValueDelegate;
this.coreIdentifier = coreIdentifier;
}
}
以下是针对 Variable 抽象类的专业解析,结合工业控制领域特性的深度分析:
1. 核心定位
该类是 工业控制系统中变量的抽象基类,作为连接以下两层的桥梁:
-
上层应用:提供类型安全的变量访问接口
-
底层硬件:通过委托模式对接不同设备的物理信号
2. 关键成员设计
2.1 核心字段
| 字段 | 类型 | 作用 |
|---|---|---|
getValueDelegate | GetValueDelegate | 抽象取值操作,实现硬件信号读取的差异化 |
setValueDelegate | SetValueDelegate | 抽象赋值操作,实现硬件信号写入的差异化 |
coreIdentifier | _PTR_DATA | 原生层变量标识结构体,包含硬件地址等元信息 |
2.2 属性设计
| 属性 | 类型 | 工业控制典型用途 |
|---|---|---|
Value | object | 统一访问接口,支持动态类型转换(如PLC中的ANY类型) |
Context | VariableContext | 区分变量所在上下文(如全局/任务/IO模块等) |
Number | int | 对应硬件寄存器/内存地址编号 |
3. 工业控制特性实现
3.1 硬件访问抽象化
// 通过委托将硬件操作与业务逻辑解耦
public delegate object GetValueDelegate(Variable variable);
public delegate void SetValueDelegate(Variable variable, object value);
// 具体实现示例(模拟量输入读取)
GetValueDelegate analogInputReader = v => {
double raw = ReadHardwareRegister(v.Number);
return raw * calibrationFactor;
};
3.2 多上下文支持
public enum VariableContext {
Global, // 全局变量
Task, // 任务专用变量
FieldbusInput, // 现场总线输入
VirtualIO // 虚拟IO信号
}
设计意图:适应不同控制层级的需求。
3.3 类型安全机制
public enum VariableType {
Double, // 模拟量
Integer, // 整型数据
Binary, // 开关量
String // 文本数据
}
// 在派生类中强制类型检查
internal sealed class AnalogVariable : Variable {
public new double Value {
get => (double)base.Value;
set => base.Value = value;
}
}
4. 运行时行为分析
4.1 值读写流程

4.2 派生类实现示例
// 数字量输入变量实现
public class DigitalInputVariable : Variable {
public DigitalInputVariable(Controller ctrl, int ioNumber)
: base(ctrl, VariableType.Binary, VariableContext.IO, 0, ioNumber,
$"DI[{ioNumber}]",
v => ReadDigitalInput(v.Number),
(v,val) => throw new InvalidOperationException("输入只读"))
{}
private static bool ReadDigitalInput(int address) {
return (ReadHardwareWord(address) & 0x01) != 0;
}
}
5. 设计优势
-
硬件无关性
通过委托模式支持不同厂商设备驱动快速接入 -
性能优化
-
避免虚方法调用开销(对比抽象方法)
-
减少值类型装箱(通过派生类强类型封装)
-
-
工业协议兼容
_PTR_DATA结构体可携带PROFINET/Modbus等协议的原始地址信息 -
安全控制
通过上下文和类型约束防止误操作(如对输入变量执行写入)
6. 典型应用场景
// 创建温度传感器变量
var tempVar = new AnalogVariable(controller,
context: VariableContext.FieldbusInput,
address: 0x4000,
name: "Temperatur1");
// 监控值变化
while(true) {
double currentTemp = tempVar.Value;
if(currentTemp > 80.0) {
TriggerAlarm();
}
Thread.Sleep(100);
}
7. 改进建议
-
线程安全增强
private readonly object _syncLock = new object();
public object Value {
get { lock(_syncLock) return getValueDelegate(this); }
set { lock(_syncLock) setValueDelegate(this, value); }
}
历史记录支持
public event EventHandler<ValueChangedArgs> ValueChanged;
DI容器集成
services.AddTransient<Variable>(sp => {
var ctx = sp.GetService<IOperationContext>();
return new AnalogVariable(ctx.Controller, ...);
});
该设计完美体现了工业控制软件对 实时性、可靠性 和 扩展性 的核心要求,是变量抽象层的经典实现范式。

393

被折叠的 条评论
为什么被折叠?



