If the “allowedness” of a PersonType
value is specific to the particular algorithm you are writing, I usually write this as an array:
var disallowedTypes = new[] {
PersonType.Employee,
PersonType.Manager,
PersonType.Contractor,
PersonType.Executive
};
foreach (var item in list.Where(p => !disallowedTypes.Contains(p.Type)))
DoSomething(item);
If this set of disallowed types is central to your application (or to a particular class), I would declare it as a static field in a static class (or the relevant class). That way your entire program (or that class) has convenient access to it, and you only need to update it in a single place if the business logic changes:
public static class Data
{
public static readonly PersonType[] DisallowedTypes = {
PersonType.Employee,
PersonType.Manager,
PersonType.Contractor,
PersonType.Executive
};
}
// [ ... ]
foreach (var item in list.Where(p => !Data.DisallowedTypes.Contains(p.Type)))
DoSomething(item);
If the set of disallowed types is inherent in the semantics of the PersonType
enum itself, I would make this very explicit by using custom attributes in the enum type itself. Of course you should think up a more descriptive name than IsAllowed
and fix the XML comment on the attribute type to explain what it really means:
/// <summary>Specifies that a <see cref="PersonType"/> value is allowed.</summary>
public sealed class IsAllowedAttribute : Attribute { }
public enum PersonType
{
Employee,
Manager,
Contractor,
Executive,
[IsAllowed]
President
}
public static class Data
{
/// <summary>This array is automatically prefilled with the
/// PersonType values that do not have an [IsAllowed] custom attribute.
/// To change this array, change the custom attributes in the
/// <see cref="PersonType"/> enum instead.</summary>
public static readonly PersonType[] DisallowedTypes;
static Data()
{
DisallowedTypes = typeof(PersonType)
.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(f => !f.IsDefined(typeof(IsAllowedAttribute), false))
.Select(f => f.GetValue(null))
.ToArray();
}
}
This way the information whether any particular enum value is allowed or not is stored in the enum itself and no-where else. That makes the code very explicit, easy to follow, and easy to modify in obviously-correct ways.