Monday, 23 January 2023

Creating a json string representing enum names and values in C#

A short blog post here demonstrating how to create a JSON string showing enum names and values for an enum in C#, simple stuff! From Linqpad 7:

void Main()
{
	var jsonEnum = EnumUtil.GenerateJsonForEnum<PasientOvertattEnum>();
	jsonEnum.Dump();	
}

public static class EnumUtil
{

	/// <summary>
	/// Generates a json string (array) for enum values
	/// Checked that it gives valid json array string here : https://jsonlint.com/
	/// </summary>
	public static string GenerateJsonForEnum<TEnum>()
	 where TEnum : struct, IConvertible
	{
		var enumItems = new List<object>();
		var sb = new StringBuilder();
		sb.AppendLine("[\n");
		bool isEnumValueFound = false;
		foreach (var enumValue in Enum.GetValues(typeof(TEnum)))
		{
			sb.AppendLine($@"	{{	""Name"": ""{enumValue}"", ""Value"": ""{(int)enumValue}""	}},");
			isEnumValueFound = true;
		}
		if (isEnumValueFound)
		{
			sb.Remove(sb.Length - 3, 1);
		}
		sb.AppendLine("\t]");
		return sb.ToString();
	}
}



This gives the following sample json string when testing:


[

  {  "Name": "Velgverdi", "Value": "0"  },
  {  "Name": "AkershusUniversitetssykehusHF", "Value": "1"  },
  {  "Name": "DiakonhjemmetSykehusAS", "Value": "2"  },
  {  "Name": "FinnmarkssykehusetHF", "Value": "3"  },
  {  "Name": "HaraldsplassDiakonaleSykehusAS", "Value": "4"  },
  {  "Name": "HelgelandssykehusetHF", "Value": "5"  },
  {  "Name": "HelseBergenHF", "Value": "6"  },
  {  "Name": "HelseFonnaHF", "Value": "7"  },
  {  "Name": "HelseFordeHF", "Value": "8"  },
  {  "Name": "HelseMoreogRomsdalHF", "Value": "9"  },
  {  "Name": "HelseNordTrondelagHF", "Value": "10"  },
  {  "Name": "HelseStavangerHF", "Value": "11"  },
  {  "Name": "LovisenbergDiakonaleSykehusAS", "Value": "12"  },
  {  "Name": "NordlandssykehusetHF", "Value": "13"  },
  {  "Name": "OsloUniversitetssykehusHF", "Value": "14"  },
  {  "Name": "SandvikaNevrosenter", "Value": "15"  },
  {  "Name": "StOlavshospitalHF", "Value": "16"  },
  {  "Name": "SykehusetiVestfoldHF", "Value": "17"  },
  {  "Name": "SykehusetInnlandetHF", "Value": "18"  },
  {  "Name": "SykehusetTelemarkHF", "Value": "19"  },
  {  "Name": "SykehusetOstfoldHF", "Value": "20"  },
  {  "Name": "SorlandetsykehusHF", "Value": "21"  },
  {  "Name": "UniversitetssykehusetNordNorgeHF", "Value": "22"  },
  {  "Name": "VestreVikenHF", "Value": "23"  },
  {  "Name": "Utenlands", "Value": "24"  },
  {  "Name": "Ukjent", "Value": "25"  }
  ]




The JSON string above has been tested and validated okay against : https://jsonlint.com/ So if you need to show the data contents of an enum into a Json, this is a simple way of doing this.

Saturday, 7 January 2023

List patterns in C# 11 - And getting a compiler error on code that should work

I have tested out list patterns in .NET 7 and C#. I am using Linqpad 7 and .NET 7.0.1. List patterns are useful I guess to compared sequences and fun to test out. The '_' discard here means to ignore the number at a given position and the '..' range here is to match anything between a given set of value and one index and then a given value at a higher index with arbitrary values between. But in one of the samples, it says you can capture variables inside list patterns. I cannot make it work, I get a compiler error. I am getting a CS0165 'Use of unassigned local variable' error when I try to access the variable(s) captured. I tried checking the crashing code also inside VsCode, still getting the error, however if I debug inside Linqpad I can see the variables that are captured got values at least.

    var someOddNumbers = new int[] { 1, 3, 5, 7, 9, 11 };
    bool resultX = someOddNumbers is [1, 3, _, _, _, 11];
    resultX.Dump("The 'someOddNumbers' equals a sequence of numbers 1,3,then three arbitrary numbers, then 11?");

    bool isOdd = someOddNumbers is [1, .., 9, 11];
    isOdd.Dump("The 'someOddNumbers' equals a sequence of numbers 1, some arbitrary numbers, then ending with 9 and 11?");
    
    result = input is [var firstOddNumber,.. var lastOddNumber];

    if (result)
    {
        Console.WriteLine($"The captured variables are: {firstOddNumber} and {lastOddNumber}"); //this lines gives the CS0165 error
    }

If I comment out the if block I can run the code sample, and in the debugger I can see firstOddNumber and lastOddNumber being set to a value at runtime. But the C# 11 compiler seems to think this is illeagal code since it is using an unintialized variable. I expected to not get a compiler error and be able to also capture the variables defined in the list pattern. I cannot understand the usage of such variables if I cannot use them. I understand that these variables might not be captured if the list pattern does not match, but even when checking if a match was present, I got the compilation error. I can however run the code, just not access the variables.