控制器参数模板类ControllerParameter<T>的C#实现

internal class ControllerParameter<T> : TypedParameter<T> where T : IComparable
{
    private readonly Controller controller;

    internal ControllerParameter(Controller controller, string name, PrimitiveType myType)
        : this(controller, name, myType, ParameterContext.System, 0)
    {
    }

    internal ControllerParameter(Controller controller, string name, PrimitiveType myType, ParameterContext context, int contextKey)
        : base(name, myType, context, contextKey)
    {
        this.controller = controller;
    }

    protected override object getValue()
    {
        int number = ParameterInfoProvider.GetNumber(base.Name);
        if (base.ValueType == PrimitiveType.String)
        {
            StringBuilder stringBuilder = new StringBuilder(10000);
            ExceptionResolver.ResolveThrow(controller, Wrapper.AerParmGetValueString(controller.Handle.Value, (int)base.Context, base.ContextKey, number, stringBuilder, stringBuilder.Capacity));
            return stringBuilder.ToString();
        }

        double pdValue_ = 0.0;
        ExceptionResolver.ResolveThrow(controller, Wrapper.AerParmGetValue(controller.Handle.Value, (int)base.Context, base.ContextKey, number, ref pdValue_));
        TypeCode typeCode = TypeCode.Object;
        switch (base.ValueType)
        {
            case PrimitiveType.Double:
                typeCode = TypeCode.Double;
                break;
            case PrimitiveType.Integer:
                typeCode = TypeCode.Int32;
                break;
            case PrimitiveType.Long:
                typeCode = TypeCode.Int64;
                break;
            case PrimitiveType.Single:
                typeCode = TypeCode.Single;
                break;
        }

        return Convert.ChangeType(pdValue_, typeCode);
    }

    protected override void setValue(object value)
    {
        int number = ParameterInfoProvider.GetNumber(base.Name);
        if (base.ValueType == PrimitiveType.String)
        {
            string text = (string)value;
            ExceptionResolver.ResolveThrow(controller, Wrapper.AerParmSetValueString(controller.Handle.Value, (int)base.Context, base.ContextKey, number, text, text.Length));
        }
        else
        {
            double dValue_ = Convert.ToDouble(value);
            ExceptionResolver.ResolveThrow(controller, Wrapper.AerParmSetValue(controller.Handle.Value, (int)base.Context, base.ContextKey, number, dValue_));
        }
    }
}

以下是针对 ControllerParameter<T> 类的详细中文解析:


1. 类定义与泛型约束

internal class ControllerParameter<T> : TypedParameter<T> where T : IComparable
  • 作用
    这是一个 内部类(仅限当前程序集访问),继承自泛型基类 TypedParameter<T>,并约束泛型类型 T 必须实现 IComparable 接口(确保值可比较)。


2. 构造函数

简化构造
internal ControllerParameter(Controller controller, string name, PrimitiveType myType)
    : this(controller, name, myType, ParameterContext.System, 0)
  • 功能
    提供快速初始化,默认设置参数上下文为 System,上下文键为 0,并转发到完整构造函数。

完整构造
internal ControllerParameter(Controller controller, string name, PrimitiveType myType, 
                           ParameterContext context, int contextKey)
    : base(name, myType, context, contextKey)
{
    this.controller = controller;
}
  • 关键点

    • 通过 base 调用基类构造函数,初始化参数名称、类型、上下文和键。

    • 存储 controller 实例引用,用于后续与底层硬件/驱动交互。


3. 核心方法解析

getValue():获取参数值
protected override object getValue()
{
    int number = ParameterInfoProvider.GetNumber(base.Name); // 获取参数编号
    if (base.ValueType == PrimitiveType.String) // 字符串类型特殊处理
    {
        StringBuilder stringBuilder = new StringBuilder(10000);
        ExceptionResolver.ResolveThrow(controller, 
            Wrapper.AerParmGetValueString(controller.Handle.Value, (int)base.Context, 
                                         base.ContextKey, number, stringBuilder, stringBuilder.Capacity));
        return stringBuilder.ToString();
    }

    double pdValue_ = 0.0;
    ExceptionResolver.ResolveThrow(controller, 
        Wrapper.AerParmGetValue(controller.Handle.Value, (int)base.Context, 
                               base.ContextKey, number, ref pdValue_));

    // 根据类型转换返回值
    TypeCode typeCode = TypeCode.Object;
    switch (base.ValueType)
    {
        case PrimitiveType.Double: typeCode = TypeCode.Double; break;
        case PrimitiveType.Integer: typeCode = TypeCode.Int32; break;
        case PrimitiveType.Long:    typeCode = TypeCode.Int64; break;
        case PrimitiveType.Single: typeCode = TypeCode.Single; break;
    }
    return Convert.ChangeType(pdValue_, typeCode);
}
  • 流程

    1. 通过 ParameterInfoProvider 将参数名转换为唯一编号。

    2. 字符串类型:调用原生方法 AerParmGetValueString,预分配 StringBuilder 缓冲区接收结果。

    3. 数值类型

      • 调用 AerParmGetValue 获取 double 类型的原始值。

      • 根据 PrimitiveType 转换为目标类型(如 intfloat 等)。

  • 异常处理:通过 ExceptionResolver.ResolveThrow 统一处理原生调用错误。

setValue():设置参数值
protected override void setValue(object value)
{
    int number = ParameterInfoProvider.GetNumber(base.Name);
    if (base.ValueType == PrimitiveType.String)
    {
        string text = (string)value;
        ExceptionResolver.ResolveThrow(controller, 
            Wrapper.AerParmSetValueString(controller.Handle.Value, (int)base.Context, 
                                         base.ContextKey, number, text, text.Length));
    }
    else
    {
        double dValue_ = Convert.ToDouble(value); // 统一转为double
        ExceptionResolver.ResolveThrow(controller, 
            Wrapper.AerParmSetValue(controller.Handle.Value, (int)base.Context, 
                                  base.ContextKey, number, dValue_));
    }
}
  • 关键逻辑

    • 字符串:直接调用原生方法 AerParmSetValueString 设置。

    • 数值:先统一转为 double,再通过 AerParmSetValue 设置。

  • 安全性:依赖 Convert.ToDouble 和异常处理器保证类型安全。


4. 设计意图分析

  • 抽象层次
    封装了与底层控制器(如PLC、嵌入式设备)的参数交互细节,向上提供类型安全的接口。

  • 性能优化

    • 字符串处理使用预分配的 StringBuilder 避免频繁内存分配。

    • 数值类型统一通过 double 中转,简化原生接口调用。

  • 扩展性
    通过 PrimitiveType 和泛型支持多种数据类型,未来可轻松添加新类型。


5. 典型使用场景

假设有一个温度控制器,其参数可能如下使用:

// 定义温度参数(double类型)
var tempParam = new ControllerParameter<double>(controller, "Temperature", PrimitiveType.Double);

// 设置温度值
tempParam.setValue(25.5); 

// 读取当前温度
double currentTemp = (double)tempParam.getValue();

总结

该类是 硬件控制层与业务逻辑层之间的适配器,核心价值在于:

  1. 类型安全:通过泛型和类型检查避免运行时错误。

  2. 统一异常处理:集中管理原生调用错误。

  3. 简化调用:隐藏复杂的原生API细节,提供直观的C#接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值