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;
}