我有一个与外部库连接的程序,除了其他外,它还有一个无符号的12位值打包在一个更大的结构中。
这曾经是8位,所以我们只是把它编组为一个字节。
现在它是12位...我可以使用ushort,但这会产生(a)范围检查和(b)编组的问题。
是否有一种简单的方法来实现这样的约束数值类型,我不必覆盖每个赋值和比较方法?
答案 0 :(得分:17)
尝试此操作(此示例显示自定义Int64类型)
public class MyCustomInt64 : CustomValueType<MyCustomInt64, Int64>
{
private MyCustomInt64(long value) : base(value) {}
public static implicit operator MyCustomInt64(long value) { return new MyCustomInt64(value); }
public static implicit operator long(MyCustomInt64value custom) { return custom._value; }
}
在构造函数中实现您喜欢的内容以应用constriants。
用法
MyCustomInt64 myInt = 27; //use as like any other value type
这是可重用的基本自定义值类型(如果需要,添加更多运算符)
public class CustomValueType<TCustom, TValue>
{
protected readonly TValue _value;
public CustomValueType(TValue value)
{
_value = value;
}
public override string ToString()
{
return _value.ToString();
}
public static bool operator <(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return Comparer<TValue>.Default.Compare(a._value, b._value) < 0;
}
public static bool operator >(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return !(a < b);
}
public static bool operator <=(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return (a < b) || (a == b);
}
public static bool operator >=(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return (a > b) || (a == b);
}
public static bool operator ==(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return a.Equals((object)b);
}
public static bool operator !=(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return !(a == b);
}
public static TCustom operator +(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return (dynamic) a._value + b._value;
}
public static TCustom operator -(CustomValueType<TCustom, TValue> a, CustomValueType<TCustom, TValue> b)
{
return ((dynamic) a._value - b._value);
}
protected bool Equals(CustomValueType<TCustom, TValue> other)
{
return EqualityComparer<TValue>.Default.Equals(_value, other._value);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CustomValueType<TCustom, TValue>)obj);
}
public override int GetHashCode()
{
return EqualityComparer<TValue>.Default.GetHashCode(_value);
}
}
答案 1 :(得分:14)
您应该创建一个覆盖隐式转换运算符的结构:
struct PackedValue {
private PackedValue(ushort val) {
if(val >= (1<<12)) throw new ArgumentOutOfRangeException("val");
this._value = val;
}
private ushort _value;
public static explicit operator PackedValue(ushort value) {
return new PackedValue(value);
}
public static implicit operator ushort(PackedValue me) {
return me._value;
}
}