Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# sizeof(enum) alternative? (to workaround resharper false error)?

In C# I've got some "safe" API code related to UAC elevation. It involves getting the size of an enum (as follows)

int myEnumSize = sizeof (MyEnum);

The code itself is valid, compiles, works correctly etc. But Resharper falsely flags it as a an error ("Cannot use unsafe construct in safe context") within the solution. (Starting with version 2.0 of C#, applying sizeof to built-in types no longer requires that unsafe mode be used.) I love Resharper, and I love the solution analysis, but with this code in the solution I have a big red dot in the corner that makes me always think something is broken. If I tell resharper to ignore this error it comes back within minutes.

I would raise the issue with JetBrains, but I looked on their tracker and they've already got one logged that has been ignored since March. Looking further they have at least two other instances of this logged going back several years, both were dismissed with a "no-repro" status. I don't want to sign-up to their tracker just to up-vote this bug. I could still end-up holding my breath for years. The fastest way forward is just to work-around the issue.

What is the best alternative that is still correct and has the least chance of causing a maintainer any trouble later on?

I could hard-code it to:

int myEnumSize = 4;  

Is there are more correct solution? -- which doesn't use sizeof(enum)?

Btw:

 Marshal.SizeOf() 

is completely "safe" but returns the wrong size.

PS. The code in questions is heavily influenced by the UACSelfElvation demo code from Microsoft. If you want more details. But I don't think they are relevant.

like image 694
DanO Avatar asked Nov 18 '10 20:11

DanO


2 Answers

Looks ugly, but may work:

int myEnumSize = Marshal.SizeOf(Enum.GetUnderlyingType(typeof(MyEnum)));


Edit by John Gietzen:
Proof:
enum Enum1 : sbyte { A, B, C, D }
enum Enum2 : short { A, B, C, D }
enum Enum3 : int { A, B, C, D }
enum Enum4 : long { A, B, C, D }

enum Enum5 : byte { A, B, C, D }
enum Enum6 : ushort { A, B, C, D }
enum Enum7 : uint { A, B, C, D }
enum Enum8 : ulong { A, B, C, D }

sizeof(Enum1): 1
sizeof(Enum2): 2
sizeof(Enum3): 4
sizeof(Enum4): 8
sizeof(Enum5): 1
sizeof(Enum6): 2
sizeof(Enum7): 4
sizeof(Enum8): 8

Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum1))): 1
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum2))): 2
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum3))): 4
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum4))): 8
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum5))): 1
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum6))): 2
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum7))): 4
Marshal.SizeOf(Enum.GetUnderlyingType(typeof(Enum8))): 8

like image 118
max Avatar answered Sep 23 '22 12:09

max


The correct solution would be to add a comment before this line stating that the warning generated by the tool is incorrect. This will prevent future maintainers from becoming confused and trying to fix something that's not broken.

like image 42
cdhowie Avatar answered Sep 26 '22 12:09

cdhowie