I'm trying to get a sorted list of all environment variables for logging purpose using System.Environment.GetEnvironmentVariables() which returns an IDictionary.
According to the documentation IDictionary does not provide any functionality for sorting: IDictionary Interface
The IDictionary interface allows the contained keys and values to be enumerated, but it does not imply any particular sort order.
As kind of workaround i came up with something like this:
var dictionary = Environment.GetEnvironmentVariables();
var keyList = dictionary.Keys.OfType<string>().ToList();
keyList.Sort();
int maxKeyLen = keyList.Max(key => ((string)key).Length);
string logMessage = "";
foreach (string key in keyList)
{
logMessage =
logMessage
Environment.NewLine
(key ": ").PadRight(maxKeyLen 2)
dictionary[key];
}
Console.WriteLine(logMessage);
Update
Due to the solution of @canton7 I changed the upper code to this:
var sortedEntries = Environment.GetEnvironmentVariables().Cast<DictionaryEntry>().OrderBy(entry => entry.Key);
int maxKeyLen = sortedEntries.Max(entry => ((string)entry.Key).Length);
string logMessage = "";
foreach (var entry in sortedEntries)
{
logMessage =
logMessage
Environment.NewLine
(entry.Key ": ").PadRight(maxKeyLen 2)
entry.Value;
}
Console.WriteLine(logMessage);
CodePudding user response:
Environment.GetEnvironmentVariables()
returns a non-generic IDictionary
. IDictionary
implements IEnumerable
, and even though this isn't clear from the interface without reading the documentation, every member you get when iterating over it is a DictionaryEntry
.
A DictionaryEntry
is basically just a pre-generics KeyValuePair<object, object>
.
Linq provides two methods for moving from a non-generic IEnumerable
to a generic IEnumerable<T>
: Cast<T>()
and OfType<T>()
. In this case, since we know that every element is a DictionaryEntry
, we can use Cast<DictionaryEntry>()
.
So:
var entries = Environment.GetEnvironmentalVariables().Cast<DictionaryEntry>();
Now we've got an IEnumerable<DictionaryEntry>
. We could just sort this:
var sortedEntries = entries.OrderBy(x => (string)x.Key);
Or we could turn it into a KeyValuePair<string, string>
first to make it easier to work with:
var entries = Environment.GetEnvironmentalVariables().Cast<DictionaryEntry>()
.Select(x => KeyValuePair.Create((string)x.Key, (string)x.Value));
var sortedEntries = entries.OrderBy(x => x.Key);