参数系统的基类Parameter抽象类

cs 复制代码
public abstract class Parameter : INamed<string>
{
    private readonly string name;

    private readonly PrimitiveType myType;

    private readonly int contextKey;

    private readonly ParameterContext context;

    private object cachedValue;

    public string Name => name;

    public ParameterBounds Bounds => getBounds();

    public object Value
    {
        get
        {
            cachedValue = getValue();
            return cachedValue;
        }
        set
        {
            ValidTypeException(value);
            setValue(value);
            cachedValue = value;
        }
    }

    internal double ValueDouble
    {
        get
        {
            return (double)getValue();
        }
        set
        {
            switch (ValueType)
            {
                case PrimitiveType.Integer:
                    setValue((int)value);
                    break;
                case PrimitiveType.Double:
                    setValue(value);
                    break;
                case PrimitiveType.Single:
                    setValue((float)value);
                    break;
                case PrimitiveType.Long:
                    setValue((long)value);
                    break;
                default:
                    throw new InvalidCastException();
            }
        }
    }

    internal object CachedValue
    {
        get
        {
            if (cachedValue == null)
            {
                return Value;
            }

            return cachedValue;
        }
    }

    internal int Number => ParameterInfoProvider.GetNumber(name);

    public object Default => ParameterInfoProvider.GetDefault(name);

    public PrimitiveType ValueType => myType;

    public ParameterContext Context => context;

    public int ContextKey => contextKey;

    internal void WithinBoundsException(Controller controller, object value)
    {
        if (WithinBounds(value) != 0)
        {
            ExceptionResolver.ResolveThrow(controller, ExceptionResolver.CreateErrorStructure(ErrorCode.ParameterValueOutOfRange));
        }
    }

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

    internal Parameter(string name, PrimitiveType myType, ParameterContext context, int contextKey)
    {
        this.name = name;
        this.myType = myType;
        this.context = context;
        this.contextKey = contextKey;
    }

    protected abstract ParameterBounds getBounds();

    internal void InvalidateCache()
    {
        cachedValue = null;
    }

    protected abstract void setValue(object value);

    protected abstract object getValue();

    internal int WithinBounds(object value)
    {
        if (!Bounds.Exists)
        {
            if (value is double d)
            {
                if (double.IsNegativeInfinity(d) || double.IsNaN(d))
                {
                    return -1;
                }

                if (double.IsPositiveInfinity(d))
                {
                    return 1;
                }
            }
            else if (value is float f)
            {
                if (float.IsNegativeInfinity(f) || float.IsNaN(f))
                {
                    return -1;
                }

                if (float.IsPositiveInfinity(f))
                {
                    return 1;
                }
            }

            return 0;
        }

        if ((value as IComparable).CompareTo(Bounds.Min) < 0)
        {
            return -1;
        }

        if ((value as IComparable).CompareTo(Bounds.Max) > 0)
        {
            return 1;
        }

        return 0;
    }

    internal void ValidTypeException(object value)
    {
        if (ValueType switch
        {
            PrimitiveType.Integer => typeof(int),
            PrimitiveType.Double => typeof(double),
            PrimitiveType.Single => typeof(float),
            PrimitiveType.Long => typeof(long),
            PrimitiveType.String => typeof(string),
            _ => typeof(object),
        } != value.GetType())
        {
            throw new InvalidCastException();
        }
    }
}

以下是针对 Parameter 抽象类的深度解析,从设计模式到实现细节的全面分析:


1. 核心职责

作为 参数系统的基类,主要功能包括:

  • 类型安全的参数值管理:支持多种原始类型(int/double/float/long/string)

  • 边界验证:自动检查值范围有效性

  • 缓存机制:减少频繁访问底层系统的开销

  • 上下文感知:区分系统级/任务级等不同参数来源


2. 关键设计模式

(1)模板方法模式
  • 抽象钩子方法:强制子类实现特定硬件访问逻辑

  • 通用逻辑复用:边界检查/类型验证等在基类完成

(2)装饰器模式
cs 复制代码
public object Value {
    get {
        cachedValue = getValue(); // 实际获取值
        return cachedValue;
    }
    set {
        ValidTypeException(value); // 验证类型
        setValue(value);           // 实际设置值
        cachedValue = value;       // 更新缓存
    }
}
(3)策略模式
cs 复制代码
internal double ValueDouble {
    set {
        switch(ValueType) { // 根据类型选择转换策略
            case PrimitiveType.Integer: setValue((int)value); break;
            case PrimitiveType.Double:  setValue(value); break;
            // ...
        }
    }
}

3. 核心组件分析

组件 类型/接口 功能
ParameterBounds 值对象 存储参数最小/最大值
ParameterInfoProvider 静态类 提供元数据(编号/默认值)
PrimitiveType 枚举 定义支持的参数类型
ParameterContext 枚举 参数作用域分类

4. 关键流程

(1)值获取流程

(2)值设置流程

5. 类型安全设计

机制 实现方式 示例
编译时检查 泛型约束 where T : IComparable
运行时验证 ValidTypeException 拒绝 string 赋值给 double 参数
安全转换 ValueDouble 属性 自动处理浮点到整型的转换

6. 典型子类实现

cs 复制代码
internal class HardwareParameter : Parameter 
{
    private readonly IntPtr _deviceHandle;
    
    protected override object getValue() {
        double val = 0;
        Wrapper.AerParamRead(_deviceHandle, Name, ref val);
        return Convert.ChangeType(val, ValueType);
    }
    
    protected override void setValue(object value) {
        double dVal = Convert.ToDouble(value);
        Wrapper.AerParamWrite(_deviceHandle, Name, dVal);
    }
    
    protected override ParameterBounds getBounds() {
        double min=0, max=0;
        Wrapper.AerParamGetBounds(_deviceHandle, Name, ref min, ref max);
        return new ParameterBounds(min, max);
    }
}

7. 改进建议

  1. 线程安全增强
cs 复制代码
private readonly object _syncLock = new object();
public object Value {
    get {
        lock(_syncLock) {
            if (_cacheExpired) {
                cachedValue = getValue();
                _cacheExpired = false;
            }
            return cachedValue;
        }
    }
}

DI 集成

cs 复制代码
public interface IParameterFactory {
    Parameter Create(string name, ParameterContext ctx);
}

异步支持

cs 复制代码
public async Task<object> GetValueAsync() {
    return await Task.Run(() => Value);
}

更智能的缓存

cs 复制代码
private DateTime _lastUpdated;
public bool IsCacheValid => 
    (DateTime.Now - _lastUpdated) < CacheTimeout;

8. 边界条件处理

边界情况 处理方式 代码示例
无穷大值 特殊检查 double.IsInfinity(value)
NaN 值 显式拒绝 throw new ArgumentException
类型不匹配 异常抛出 ValidTypeException
超出范围 错误代码返回 WithinBounds()

总结

该抽象类的设计优势:

  • 良好的扩展性:通过抽象方法支持多种硬件平台

  • 类型安全:严格的运行时类型检查

  • 性能优化:缓存机制减少硬件访问

典型应用于:

  1. CNC系统参数管理

  2. 工业控制器配置系统

  3. 实时参数监控平台

通过增加响应式编程支持(如 IObservable)和更细粒度的变更通知,可进一步提升其在现代工业系统中的实用性。

相关推荐
盛夏绽放5 小时前
Python字符串常用方法详解
开发语言·python·c#
Tummer83638 小时前
C#+WPF+prism+materialdesign创建工具主界面框架
开发语言·c#·wpf
ghost1439 小时前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#
yngsqq10 小时前
(for 循环) VS (LINQ) 性能比拼 ——c#
c#·solr·linq
想做后端的小C11 小时前
C# 面向对象 构造函数带参无参细节解析
开发语言·c#·面向对象
炯哈哈11 小时前
【上位机——WPF】App.xml和Application类简介
xml·开发语言·c#·wpf·上位机
bestcxx11 小时前
c# UTC 时间赋值注意事项
c#·utc
酷炫码神11 小时前
C#运算符
开发语言·c#
zybsjn12 小时前
后端系统做国际化改造,生成多语言包
java·python·c#