Define “custom” integer-based type?

后端 未结 2 1238
陌清茗
陌清茗 2020-12-08 22:08

I have a program that is interfacing with an external library that, among other things, has an unsigned 12-bit value packed in a larger struct.

This used to be 8 bit

相关标签:
2条回答
  • 2020-12-08 22:28

    You should create a struct that overrides the implicit conversion operator:

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-08 22:28

    Try this (this example shows a custom Int64 type)

    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(MyCustomInt64 custom) { return custom._value; }
    }
    

    Implement what you like in the constructor to apply constriants.

    Usage

    MyCustomInt64 myInt = 27; //use as like any other value type
    

    And here is the reusable base custom value type (add more operators if needed)

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题