0

I've had a look at this question and while it solves their issue at hand, its not jumping out at me and I am still having trouble with mine.

I have the following code, where a string is being split into its prospective key/value pairs however it would normally dump this out into a <string, string> dictionary. I need the value to be in the form of a enum as follows:

public enum SortDirection
{
    asc = 0,
    desc
}

I have declared the dictionary orderBy as follows:

var orderedBy = new Dictionary<string, SortDirection>();

keyValuePair.Value is a set of key value pairs in a string one after the other.

ClientNo asc,ClientLastName asc

and the code to split this and create the dictionary is as follows.

    orderedBy = keyValuePair.Value.Split(',')
        .Select(x => x.Split(' '))
        .ToDictionary(x => x[0], (x => Enum.TryParse(x[1], false, out SortDirection direction)));

At no time will the value for x[1] be anything other than either "asc" or "desc" however I cannot seem to convert the string value to an enum on the fly.

I am getting the following error.

Cannot convert type 'System.Collections.Generic.KeyValuePair' to 'System.Collections.Generic.KeyValuePair'

How do I convert x[1] from a string ("asc", "desc") to an enum in the code above and thus populate the dictionary "orderBy" via the Linq .ToDictionary?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
si2030
  • 3,895
  • 8
  • 38
  • 87

2 Answers2

1

Since TryParse returns a bool, and you've defined the dictionary to take a SortDirection value, the call is failing.

Instead, you can use the result of TryParse as a condition, then use the value if it's successful:

var orderedBy = new Dictionary<string, SortDirection>();
var sortDirection = SortDirection.asc;
var keyValuePair = "ClientNo asc,ClientLastName asc";

orderedBy = keyValuePair.Split(',')
    .Select(x => x.Split(' '))
    .Where(x => x.Length > 1 && Enum.TryParse(x[1], false, out sortDirection))
    .ToDictionary(x => x[0],
        x => (SortDirection) Enum.Parse(typeof(SortDirection), x[1]));
Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • This `x => sortDirection` thingy actually works?! It seems like magic. – Sweeper Aug 22 '19 at 00:43
  • @Sweeper Yeah, I'm not sure if it's 100% reliable or not, but the previous line *should* set `sortDirection` to the correct value during `Enum.TryParse`. It would probably be safer to do `Enum.Parse` on the `ToDictionary` line instead, in case there is some way `sortDirection` is not accurate at the time that line executes. But in my testing it works just fine. :) – Rufus L Aug 22 '19 at 00:48
  • 1
    This is dangerous approach because it relies on side effects of .Where and .ToDictionary methods, which are implementation specific. Linq functions must be used as pure functions. The right solution would be to have `sortDirection` as a part of .Where output for each element. – C-F Aug 22 '19 at 00:49
0

If you are sure you always have valid values in your strings, just use Enum.Parse instead of Enum.TryParse. This will return a converted value instead of boolean.

If the value happenes to be incorrect, you will get an exception.

See Enum.Parse

According to examples in that article, you still have to cast the result to your enum type, but this is not a problem.

C-F
  • 1,597
  • 16
  • 25