我想为有界元素(例如具有最大值和最小值的数字)创建一个结构。但是我一直不知道如何做到这一点。 这是一个属性的示例。 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 方法中使用它,因为属性无法通过引用传递。
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;
}