In Delphi, one can write the following code:
type
TMyEnum = (meFirstValue, meSecondValue);
TInfo = record
Name: string;
Description: string;
end;
const
MyEnumDetails: array [TMyEnum] of TInfo =
(
(Name: 'First Value'; Description: 'This is the first value'),
(Name: 'Second Value'; Description: 'This is the second value')
);
This has the very nice advantage that should a new enum member be added to TMyEnum
, then the compiler will complain on the MyEnumDetails
constant definition, forcing the developer to resolve the situation before the application reaches the build machine.
As I’m now writing .Net 6 C# code within Visual Studio 2022, I’m trying to replicate the above, and in particular the fact that the compiler will stop with an error if an enum member has been left out.
I can use a Dictionary as mentioned here but this does not emit a warning/error if I forget a member of the enum in the initialization.
I know this is not strictly a constant, nor a readonly element, but in my case I’m more interested in the compiler erroring out than the constness of the dictionary.
I also tried enumerating the enum members and use a switch
statement to create the instances as needed:
foreach (var myEnum in (MyEnum[])Enum.GetValues(typeof(MyEnum)))
{
switch (myEnum)
{
case MyEnum.FirstValue:
enumDictionary.Add(myEnum, new Info("First Value", "This is the first value"));
break;
}
}
}
But then again, this does not make the compiler emit any message. I was kind of expecting to get CS8509 or IDE0072/IDE0010 but nothing comes up.
So I tried moving the switch a secondary method that only does this:
private static Info GetInfo(MyEnum myEnum)
{
switch (kind)
{
case MyEnum.FirstValue:
return new Info("First Value", "This is the first value");
}
}
And this time I did receive an error, namely the CS0161 one because GetInfo does not return a value on all code paths.
But that error won’t go if I provide a case for all enum members, only does it disappear if I provide a default
case or a return outside the switch
. And then, there are no longer any messages if an enum member is not used in the switch
statement, just like with the previous attempt.
I checked in the csproj file and could not find anything that would specifically disable the CS8509 or IDE0072/IDE0010 warnings. Looking at the options page, I did not see anything either.
What have I missed here? Is there a place unknown to me that disables the above warning?
Alternatively, do you have any other suggestion as to how I can achieve the goal of having the compiler stopping on a missing enum member?
2
Answers
We have solved this using a helper class in an unit test assembly.
Then in some unit test that uses the enum, we do:
This does not cause a build time error, but still prevents pushing such an error to prod, because we cannot merge changes that fail an unit test.
The following program will give you a
CS8509
compile error:If you comment-out the
Three
item inenum EnumTest
it will compile OK, but with the following warning instead:If you don’t want that warning, you can suppress it by surrounding the affected code with:
If you do that, you’ll still get the error if you add a new item to
enum EnumTest
without adding it to the switch.Obviously you have to enable Code Analysis for this to work!
Is that the sort of thing you’re looking for?