通用类型 BoundedComponent 结构

问题描述 投票:0回答:1

我想为有界元素(例如具有最大值和最小值的数字)创建一个结构。但是我一直不知道如何做到这一点。 这是一个属性的示例。 setfield 方法只是设置属性并引发属性更改事件的方法。

private BoundedComponent<int> nbOfItems = new BoundedComponent<int> (1, int.MaxValue);

public int NbOfItems 
        {
            get => nbOfItems ;
            set => SetField(ref nbOfItems, value);
        }


protected bool SetField<T>(
            ref T field,
            T value,
            [CallerMemberName]
            string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value))
                return false;

            field = value;
            OnPropertyChanged(propertyName);
            return true;
        }

这是我的结构

public struct BoundedComponent<T> where T : struct, IComparable<T>
    {
        private T value;
        private T minValue;
        private T maxValue;

        public BoundedComponent(T minValue, T maxValue)
        {
            this.minValue = minValue;
            this.maxValue = maxValue;
            value = minValue;
        }

        public static implicit operator T(BoundedComponent<T> d)
        {
            return d.value;
        }

        public static implicit operator BoundedComponent<T>(T val)
        {
            value = BoundValue(val);
        }

        private T BoundValue(T value) 
        {
            return value.CompareTo(maxValue) > 0 ? maxValue 
                : value.CompareTo(minValue) < 0 ? minValue : value;
        }
    }

但是我不能这样做,因为隐式运算符是静态方法,所以我无法访问我想要检查的有界元素的最小值和最大值。

我怎么能做这样的事呢?

我尝试了上述方法,并且还使用了具有属性 Value 的类,但是我无法在 setfield 方法中使用它,因为属性无法通过引用传递。

c# operator-keyword implicit
1个回答
0
投票

BoundedComponent
应该 not
T
进行转换。
T
的实例根本没有足够的信息来创建
BoundedComponent
的实例。即,
T
没有任何有关其最小值和最大值的信息。

我会将

BoundValue
方法设置为 set
value
,并将其重命名为
Set

public struct BoundedComponent<T> where T : struct, IComparable<T>
{
    private T value;
    // consider making these readonly
    private readonly T minValue;
    private readonly T maxValue;

    public BoundedComponent(T minValue, T maxValue)
    {
        this.minValue = minValue;
        this.maxValue = maxValue;
        value = minValue;
    }

    public static implicit operator T(BoundedComponent<T> d)
    {
        return d.value;
    }

    public void Set(T value) 
    {
        this.value = value.CompareTo(maxValue) > 0 ? maxValue 
            : value.CompareTo(minValue) < 0 ? minValue : value;
    }
}

您应该创建一个新的

SetField
方法来设置
BoundedComponent
。正如您所发现的,您无法使用现有的
SetField

即使你可以,现有的

SetField
的逻辑对于
BoundedComponent
来说也是不正确的。假设调用
SetField(ref nbOfItems, -1)
实际上有效 - 如果
nbOfItems
最初是
1
,这会意外引发
OnPropertyChanged
事件。

您应该记录旧值,尝试调用

Set
,并将旧值与当前值进行比较,看看它是否改变:

protected bool SetField<T>(
    ref BoundedComponent<T> field,
    T value,
    [CallerMemberName]
    string propertyName = null)
    where T: struct, IComparable<T>
{
    T old = field;
    field.Set(value);
    if (EqualityComparer<T>.Default.Equals(old, field))
        return false;
    OnPropertyChanged(propertyName);
    return true;
}
© www.soinside.com 2019 - 2024. All rights reserved.