Enumerable Flags.txt


    public class WorkingDay : EnumableFlags<Weekday, WorkingDay>
    {
        public bool Mon { get; set; }
        public bool Tue { get; set; }
        public bool Wed { get; set; }
        public bool Thu { get; set; }
        public bool Fir { get; set; }
        public bool Sat { get; set; }
        public bool Sun { get; set; }

        public override int AllFlags { get => GetEnumValue(this); set => SetEnumValue(value, this); }
        public override Weekday Flags { get => (Weekday)AllFlags; set => AllFlags = (int)value; }
    }

    public class Customer: EnumableFlags<CustomerStatus, Customer>
    {
        public bool isCreated { get; set; }
        public bool isDeleted { get; set; }
        public bool isSuspended { get; set; }
        public bool isPublished { get; set; }
        public bool isActive { get; set; }
        public bool isCleared { get; set; }
        public bool isTransferable { get; set; }
        public bool isCommonFlag { get; set; }
        public int Status
        {
            get
            {
                int result = 0;
                result += isCreated ? (int)CustomerStatus.isCreated : 0;
                result += isDeleted ? (int)CustomerStatus.isDeleted : 0;
                result += isSuspended ? (int)CustomerStatus.isSuspended : 0;
                result += isPublished ? (int)CustomerStatus.isPublished : 0;
                result += isActive ? (int)CustomerStatus.isActive : 0;
                result += isCleared ? (int)CustomerStatus.isCleared : 0;
                result += isTransferable ? (int)CustomerStatus.isTransferable : 0;
                result += isCommonFlag ? (int)CustomerStatus.isCommonFlag : 0;
                return result;
            }
            set
            {
                this.isCreated = ((CustomerStatus)value & CustomerStatus.isCreated) == CustomerStatus.isCreated;
                this.isDeleted = ((CustomerStatus)value & CustomerStatus.isDeleted) == CustomerStatus.isDeleted;
                this.isSuspended = ((CustomerStatus)value & CustomerStatus.isSuspended) == CustomerStatus.isSuspended;
                this.isPublished = ((CustomerStatus)value & CustomerStatus.isPublished) == CustomerStatus.isPublished;
                this.isActive = ((CustomerStatus)value & CustomerStatus.isActive) == CustomerStatus.isActive;
                this.isCleared = ((CustomerStatus)value & CustomerStatus.isCleared) == CustomerStatus.isCleared;
                this.isTransferable = ((CustomerStatus)value & CustomerStatus.isTransferable) == CustomerStatus.isTransferable;
                this.isCommonFlag = ((CustomerStatus)value & CustomerStatus.isCommonFlag) == CustomerStatus.isCommonFlag;
            }
        }

        public override int AllFlags { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public override CustomerStatus Flags { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
    }

    public class CustWithStatus
    {
        public int Status { get; set; }
        public bool isCreated
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isCreated) == CustomerStatus.isCreated;
            }
        }

        public bool isDeleted
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isDeleted) == CustomerStatus.isDeleted;
            }
        }

        public bool isSuspended
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isSuspended) == CustomerStatus.isSuspended;
            }
        }

        public bool isPublished
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isPublished) == CustomerStatus.isPublished;
            }
        }

        public bool isActive
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isActive) == CustomerStatus.isActive;
            }
        }

        public bool isCleared
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isCleared) == CustomerStatus.isCleared;
            }
        }

        public bool isTransferable
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isTransferable) == CustomerStatus.isTransferable;
            }
        }

        public bool isCommonFlag
        {
            get
            {
                return ((CustomerStatus)this.Status & CustomerStatus.isCommonFlag) == CustomerStatus.isCommonFlag;
            }
        }
    }

    public abstract class EnumableFlags<TEnum, T> where TEnum : struct, IComparable, IFormattable, IConvertible where T: class
    {
        internal EnumableFlags()
        {
            if (!typeof(TEnum).IsEnum) throw new Exception("TEnum must be struct enum");
            foreach(Enum x in Enum.GetValues(typeof(TEnum)))
            {
                var info = typeof(T).GetProperty(x.ToString());
                if (info == null) throw new Exception(string.Format("Class {0} must contain property {1}!", typeof(T).Name, x.ToString()));
                if (info.PropertyType != typeof(Boolean)) throw new Exception("Properties bind with Enum Flag must be a Boolean Type");
            }
        }

        internal int GetEnumValue(T value)
        {
            int result = 0;
            foreach (TEnum x in Enum.GetValues(typeof(TEnum)))
            {
                var info = value.GetType().GetProperty(x.ToString());
                bool b = (bool)info.GetValue(value);
                int tmp = (int)Enum.Parse(typeof(TEnum), x.ToString());
                result += b ? tmp : 0;
            }
            return result;
        }

        internal void SetEnumValue(object value, T cls) 
        {
            Enum status = (TEnum)value as Enum;
            foreach (Enum x in Enum.GetValues(typeof(TEnum)))
            {
                var info = cls.GetType().GetProperty(x.ToString());
                info.SetValue(cls, status.HasFlag(x));
            }
        }

        public abstract int AllFlags { get; set; }
        public abstract TEnum Flags { get; set; }
    }