N.B. I thought I'd answer the original test question myself in F# as a Kata, so this is a functional suggestion based on what I found.
I'll only talk about the versatility part of the solution, others have touched on using Linq and I think your code is already quite readable.
If you can divide the original requirement into a number of smaller rules, where each rule has the same "Shape".
This "Shape" is take a sequence of characters and return a Boolean.
So in C# we'd have:
bool LengthIsValid(string s) => s.Length >= 6 && s.Length <= 16;
bool Rule2(string s) => true; //e.g must start with Letter, or doesn't with with '-'
Now that we have each rule in the same "Shape", you can create a composite set of rules and validate them all together:
var rules = new List<Func<string, bool>>
{
LengthIsValid,
Rule2,
//etc.
};
Checking the rules is then just a matter of applying those rules to the input string:
bool CheckAllRules (string s) =>
rules
.SelectAll(rule => rule(s))
.All(b => b);
With this approach you get versatility from been able to create any number of composition of rules.
e.g. Creating Rules where the powerUsers don't need to check the length (I can be root
).
IEnumerable<Func<string, bool>> CreateRules(bool powerUser)
{
if (!powerUser)
yield return LengthIsValid;
yield return Rule2;
}
The F# version if you're interested in [here](https://gist.github.com/xdaDaveShaw/a21142852d1bf9aff772b07e2523a946)