How to implement multiple selections in a class which inherit from Enumeration
With restrictions ?
If I have five schedule types:
The first two options are versus (Fixed vs Rotated)
and the second Two options (FullTime vs PartTime)
are versus, I mean the schedule can't be fixed
and rotated
at the same time or fulltime and parttime
at the same time. but It may be Fixed and FullTime
for example.
Fixed work schedules which consists of the same number of hours and days worked per week and tend to stay consistent once the number of hours and days have been agreed upon by both the employer and the worker.
Flexible work schedules in which employees and employers work together to determine the number of hours and days of the week they are able to commit to. Full time work schedule which often require a commitment of 37 - 40 hours per week. Because of the long hours, careers with full time schedules are eligible for work benefits. These benefits can include leave, vacation and sickness, health insurance, and different retirement plan options.
Part time work schedule which is any schedule less than full time employment.
Rotating work schedule which cycle employees through day or week, swing, and night shifts. This cycle helps to distribute different shifts between all employees so that no one is stuck with just the less desirable hours.
So I did the following:
public class Schedule
{
public Schedule()
{
}
private ICollection<ScheduleDetail> _assignedWeeks;
public int Id { get; set; }
public string Name { get; set; }
public int WorkingGroupId { get; set; }
public ScheduleType ScheduleType { get; set; }
public bool IsFixed { get; }
public bool IsFlexible { get; }
public bool IsFullTime { get; }
public ICollection<ScheduleDetail> AssignedWeeks { get => _assignedWeeks; set => _assignedWeeks = value; }
}
public abstract class ScheduleType : Enumeration
{
protected ScheduleType(int value, string displayName) : base(value, displayName)
{
}
public static readonly ScheduleType Fixed
= new FixedType();
public static readonly ScheduleType Flexible
= new FlexibleType();
public static readonly ScheduleType FullTime
= new FullTimeType();
public static readonly ScheduleType PartTime
= new PartTimeType();
public static readonly ScheduleType Rotated
= new RotatedType();
private class FixedType : ScheduleType
{
public FixedType() : base(1, "Fixed Work Schedule")
{
}
}
private class FlexibleType : ScheduleType
{
public FlexibleType() : base(2, "Flexible Work Schedule")
{
}
}
private class FullTimeType : ScheduleType
{
public FullTimeType() : base(3, "Full Time Work Schedule")
{
}
}
private class PartTimeType : ScheduleType
{
public PartTimeType() : base(4, "Part Time Work Schedule")
{
}
}
private class RotatedType : ScheduleType
{
public RotatedType() : base(5, "Rotated Work Schedule")
{
}
}
}
public abstract class Enumeration : IComparable
{
private readonly int _value;
private readonly string _displayName;
protected Enumeration()
{
}
protected Enumeration(int value, string displayName)
{
_value = value;
_displayName = displayName;
}
public int Value
{
get { return _value; }
}
public string DisplayName
{
get { return _displayName; }
}
public override string ToString()
{
return DisplayName;
}
public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
{
var type = typeof(T);
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
foreach (var info in fields)
{
var instance = new T();
var locatedValue = info.GetValue(instance) as T;
if (locatedValue != null)
{
yield return locatedValue;
}
}
}
public override bool Equals(object obj)
{
var otherValue = obj as Enumeration;
if (otherValue == null)
{
return false;
}
var typeMatches = GetType().Equals(obj.GetType());
var valueMatches = _value.Equals(otherValue.Value);
return typeMatches && valueMatches;
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
{
var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
return absoluteDifference;
}
public static T FromValue<T>(int value) where T : Enumeration, new()
{
var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
return matchingItem;
}
public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
{
var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
return matchingItem;
}
private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
{
var matchingItem = GetAll<T>().FirstOrDefault(predicate);
if (matchingItem == null)
{
var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
throw new ApplicationException(message);
}
return matchingItem;
}
public int CompareTo(object other)
{
return Value.CompareTo(((Enumeration)other).Value);
}
}
So based on the user selection for a specific option or set of options, I have to call a method to set flags (IsFixed,...)
in the Schedule class to control the the scheduledetails class in (Fixed and rotated) and the number of hours for(full time and part time)
I'll be grateful for any suggestions or recommendations ?
The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.
Enums cannot inherit from other enums. In fact all enums must actually inherit from System. Enum . C# allows syntax to change the underlying representation of the enum values which looks like inheritance, but in actuality they still inherit from System.
Enum Flags Attribute The idea of Enum Flags is to take an enumeration variable and allow it hold multiple values. It should be used whenever the enum represents a collection of flags, rather than representing a single value. Such enumeration collections are usually manipulated using bitwise operators.
Nope. it is not possible. Enum can not inherit in derived class because by default Enum is sealed.
You're overcomplicating this too much. The first issue I suspect is you (or your business analyst) don't have enough grasp on the busines subject - i.e. shift. What you have here are two, different enumerations:
public enum ScheduleType
{
Unknown = 0,
Fixed,
Rotated
}
public enum ScheduleLoad
{
Unknown = 0,
FullTime,
PartTime
}
Next, in the UI you need two different dropdown boxes / radio groups to allow the user to arrange the shift layout, then save this in two different properties of your object.
However, if you insist on having this in one enumeration, thus one propery with flagged enum values, you need to validate the user input before saving the flags to you store.
[Flags]
public enum ShiftLayout
{
Unknown = 0,
Fixed = 1,
Rotated = 2,
FullTime = 4,
PartTime = 8,
Flexible = 16
}
Then the validation is performed like this:
public bool IsShiftLayoutValid(ShiftLayout layout)
{
var isValid = layout.HasFlag(ShiftLayout.Flexible)
&& (layout & ~ShiftLayout.Flexible) == ShiftLayout.Unknown;
if (!isValid && !layout.HasFlag(ShiftLayout.Flexible))
{
var hasValidSchedule = (layout.HasFlag(ShiftLayout.Fixed) && !layout.HasFlag(ShiftLayout.Rotated))
|| layout.HasFlag(ShiftLayout.Rotated);
var hasValidTime = (layout.HasFlag(ShiftLayout.FullTime) && !layout.HasFlag(ShiftLayout.PartTime))
|| layout.HasFlag(ShiftLayout.PartTime);
isValid = hasValidSchedule && hasValidTime;
}
return isValid;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With