# Building a string representing 50+ ActiveDirectory options

I have a switch statement used to handle options that a user selected (stored in an array). The array is iterated through, and for each element (enum object) in the array, an appropriate action is performed. However, the enum has over 50 items, so the switch statement is very long.

The items are all necessary and related, so they cannot be moved or removed. They also each call a method or get a property of an object, so no dictionaries. Are there any other options to make this shorter?

public string GetUserAttributes(UserPrincipal user,
ActiveDirectoryUserAttribute[] attributes)
{
var userAsDirectoryEntry
= (DirectoryEntry)user.GetUnderlyingObject();
var userAttributes = string.Empty;
foreach (ActiveDirectoryUserAttribute attribute in attributes)
{
switch (attribute)
{
case ActiveDirectoryUserAttribute.AccountExpirationDate:
userAttributes += AttributeToString(
user.AccountExpirationDate.ToString());
break;
case ActiveDirectoryUserAttribute.AccountLockoutTime:
userAttributes += AttributeToString(
user.AccountLockoutTime.ToString());
break;
case ActiveDirectoryUserAttribute.Assistant:
userAttributes += AttributeToString(
userAsDirectoryEntry.Properties[AttributeAssistant]
.Value.ToString());
break;
userAttributes += AttributeToString(
break;
...
}
}
return userAttributes;
}

• You can use Reflection: it can be an elegant solution and the whole switch disappears, but one condition is needed: the methods you call... are they all without input parameters (like property getters do)? If yes, I'll post a code snippet with the solution; otherwise, a switch/enum or a dictionary is necessary. – Massimiliano Kraus May 29 '16 at 14:58
• @MK87 Some of the methods do require parameters, and are not just property getters/setters. – Michael Brandon Morris May 30 '16 at 2:33
• Mhm... can you add a snippet of a method with parameters in your code? Where you get the parameters from? – Massimiliano Kraus May 30 '16 at 9:25
• @MK87 The only parameters are the UserPrincipal and the DirectoryEntry. They are in the form GetSomeString(UserPrincipal user, DirectoryEntry userAsDirectoryEntry). – Michael Brandon Morris May 30 '16 at 10:12

You can put the switch-cases into a dictionary to reduce the boilerplate case and break. The foreach and the string concatenation part can also be reduced with string.Concat(...) or string.Join(delimiter, ...):

public string GetUserAttributes(UserPrincipal user, ActiveDirectoryUserAttribute[] attributes)
{
var userAsDirectoryEntry = (DirectoryEntry)user.GetUnderlyingObject();

var getters = new Dictionary<ActiveDirectoryUserAttribute, Func<object>>();
getters[ActiveDirectoryUserAttribute.AccountExpirationDate] = () => user.AccountExpirationDate;
getters[ActiveDirectoryUserAttribute.AccountLockoutTime] = () => user.AccountLockoutTime;
getters[ActiveDirectoryUserAttribute.Assistant] = () => userAsDirectoryEntry.Properties[AttributeAssistant].Value;
// ...

// just concat them directly, like you are doing now
return string.Concat(attributes.Select(attr => getters[attr]()));

// or, you can separate them with a comma, or anything :
return string.Join(", ", attributes
.Select(attr => getters[attr]()));
}


You can also use the collection initializer for dictionary to cut down some letters :

var getters = new Dictionary<ActiveDirectoryUserAttribute, Func<object>>
{
// C# 6
[ActiveDirectoryUserAttribute.AccountExpirationDate] = () => user.AccountExpirationDate,
[ActiveDirectoryUserAttribute.AccountLockoutTime] = () => user.AccountLockoutTime,

// older version
{ ActiveDirectoryUserAttribute.Assistant, () => userAsDirectoryEntry.Properties[AttributeAssistant].Value },