Home > other >  How do I map enums to a class property
How do I map enums to a class property

Time:01-28

I have an enum that holds feature names such as

public enum FeatureNames{
  [Description("Amazing Feature")]
  AmazingFeature,
  [Description("Amazing New Feature")]
  AmazingNewFeature
}

I have a domain entity that has properties representing each of the feature which indicates if the feature is turned on or off

public class CompanyAccount{
  public bool IsAmazingFeatureEnabled{get;set;}
  public bool IsAmazingNewFeatureEnabled{get;set;}
}

This is how the existing application was written and hence I don't want to make drastic changes to DB at this point. So now I am trying to write a genric method that will take in a string or enum value indicating feature and check if the property matching the same feature is enabled or not(true or false).

public bool IsEnabled(FeatureNames featureName){
  if(featureName is FeatureNames.AmazingFeature){
    return companyAccount.IsAmazingFeatureEnabled;
  }
  else if(featureName is FeatureNames.AmazingNewFeature){
    return companyAccount.IsAmazingNewFeatureEnabled;
  }

Is there a better way to handle this? Can we avoid the if condition?

CodePudding user response:

You could use a switch expression (C# 8.0)

public bool IsEnabled(FeatureNames featureName) =>
    featureName switch {
        FeatureNames.AmazingFeature => companyAccount.IsAmazingFeatureEnabled,
        FeatureNames.AmazingNewFeature => companyAccount.IsAmazingNewFeatureEnabled,
        _ => false
    };

or use a throw expression in the default case.

        _ => throw new NotImplementedException($"{featureName} not implemented")

Another approach would be to convert the enum into a flags enum and to add a property returning the state as flag set.

[Flags]
public enum FeatureNames {
    None = 0,
    AmazingFeature = 1,
    AmazingNewFeature = 2 // use powers of 2 for all values
}
public class CompanyAccount{
 public bool IsAmazingFeatureEnabled { get; set; }
 public bool IsAmazingNewFeatureEnabled { get; set; }

 public FeatureNames State {
   get {
     var flags = FeatureNames.None;
     if (IsAmazingFeatureEnabled) flags = flags | FeatureNames.AmazingFeature; 
     if (IsAmazingNewFeatureEnabled) flags = flags | FeatureNames.AmazingNewFeature; 
     return flags;
   }
 }
}

Then you can test the state with

if (companyAccount.State.HasFlag(FeatureNames.AmazingFeature)) ...

Using the flag enums, we could turn things around and store the state as flags and then put the logic in the Boolean properties (showing just one property here):

private FeatureNames _state;

public bool IsAmazingFeatureEnabled
{
    get => _state.HasFlag(FeatureNames.AmazingFeature);
    set => _state = value 
        ? _state | FeatureNames.AmazingFeature
        : _state & ~FeatureNames.AmazingFeature;
}
  •  Tags:  
  • Related