Collapsible checkboxes from a list separated by commas or the whole

I have XML that contains several flags, some of them are unsigned 32-bit integers, and others are unsigned 64-bit integers. Some of them are written in a comma-separated list, while others are in hexadecimal style.

See this example:

<Color>Blue,Red</Color> <Color>0xC</Color> 

Since I do not want to write a method to parse each enumeration, I decided to use a general method. But Visual Studio will not let me create a solution. Here is my method:

 public static T ParseFlags<T>(string value) where T : struct { T result = (T)((object)0); string[] array; // Remove white spaces and delimit string if it is comma-separated if (ParseDelimitedString(value, ',', out array)) { for (int i = 0; i < array.Length; i++) { T flag = (T)((object)0); // Check if value is member of enumeration if (Enum.TryParse<T>(array[i], out flag)) { result |= (T)((object)flag); } } } else { switch (Type.GetTypeCode(Enum.GetUnderlyingType(typeof(T)))) { // Remove hex characters and parse node inner text case TypeCode.UInt32: result = (T)((object)ParseUint(value)); break; case TypeCode.UInt64: result = (T)((object)ParseUlong(value)); break; } } return result; } 

The error message I get is:

Error 1 Operator '| = 'cannot be applied to operands of type "T" and' T '

Is there any way to do this?

+4
source share
4 answers

You are doing a great job that can be done for you. For example, if your enum declared using FlagsAttribute , then Enum.Parse will parse comma-separated values ​​for you.

 public static T ParseFlags<T>(string value) where T : struct { T result; ulong temp; if (Enum.TryParse(value, out result)) { return result; } string hexNum = value.StartsWith("0x") ? value.Substring(2) : value; if (ulong.TryParse(hexNum, NumberStyles.HexNumber, null, out temp)) { return (T)Enum.ToObject(typeof(T), temp); } throw new ArgumentException("value could not be parsed"); } 

I tested this with various types of Flags enumerations with short , int and ulong support values.

+6
source

If you know what type of enumeration you are processing:

  [Fact] public void when_parsing_options_then_can_combine_flags() { var values = "Singleline | Compiled"; var options = values.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Select(value => (RegexOptions)Enum.Parse(typeof(RegexOptions), value)) .Aggregate(RegexOptions.None, (current, value) => current |= value); Assert.Equal(RegexOptions.Singleline | RegexOptions.Compiled, options); } 
+1
source

Try the following:

 public static T ParseFlags<T>(string value) where T : struct { long result = 0L; string[] array; // Remove white spaces and delimit string if it is comma-separated if (ParseDelimitedString(value, ',', out array)) { for (int i = 0; i < array.Length; i++) { T flag = default(T); // Check if value is member of enumeration if (Enum.TryParse<T>(array[i], out flag)) { result |= (long)flag; } } } else { switch (Type.GetTypeCode(Enum.GetUnderlyingType(typeof(T)))) { // Remove hex characters and parse node inner text case TypeCode.UInt32: result = ParseUint(value); break; case TypeCode.UInt64: result = ParseUlong(value); break; } } return (T)((object)result); } 

Hope this helps.

0
source

The "| =" use in this fragment makes me think that you wanted to use Enum as a bitrate, not just the old Enum. If so, you should make a small change - declare the local "result" as int and adjust the castes accordingly, then your return statement should be "return (T) (object) result;". This line with "|" it will look like this: "result | = (int) (object) flag;". There may be a better answer, but note that the enumerations are integers , and your bitmap script is pretty well covered by this solution, unless there are situations I missed or you didn't specify.

0
source

All Articles