2010-11-18 10 views
6

In C# habe ich einen "sicheren" API-Code für die UAC-Erhöhung. Es geht um die Größe eines Enum bekommen (wie folgt)C# sizeof (enum) Alternative? (Um Workaround Nachschärfen falscher Fehler)?

int myEnumSize = sizeof (MyEnum); 

Der Code selbst gültig ist, kompiliert, funktioniert einwandfrei etc. Aber ReSharper fälschlicherweise Flaggen es als einen Fehler („nicht unsicher Konstrukt in sicheren Kontext verwenden können“) innerhalb der Lösung. (Starting with version 2.0 of C#, applying sizeof to built-in types no longer requires that unsafe mode be used.) Ich liebe Resharper, und ich liebe die Lösung Analyse, aber mit diesem Code in der Lösung habe ich einen großen roten Punkt in der Ecke, die mich immer denken, dass etwas gebrochen ist. Wenn ich Resharper sage, um diesen Fehler zu ignorieren, kommt er innerhalb von Minuten zurück.

Ich würde das Problem mit JetBrains aufwerfen, aber ich schaute auf ihren Tracker und sie haben bereits einen geloggt, der seit März ignoriert wurde. Wenn man weiter schaut, haben sie mindestens zwei weitere Fälle, die mehrere Jahre zurückliegen, beide wurden mit einem "No-Repro" Status entlassen. Ich möchte mich nicht bei ihrem Tracker anmelden, nur um diesen Bug abzustimmen. Ich könnte immer noch den Atem anhalten für Jahre. Der schnellste Weg nach vorne ist nur, um das Problem zu umgehen.

Was ist die beste Alternative, die immer noch korrekt ist und die geringste Chance hat, dem Betreuer später irgendwelche Probleme zu bereiten?

Ich konnte hart Code es an:

int myEnumSize = 4; 

Gibt es mehr richtige Lösung? - die nicht sizeof (enum) verwendet?

Btw:

Marshal.SizeOf() 

ist vollständig "sicher", sondern gibt die falsche Größe.

PS. Der Code in Fragen wird stark von dem Democode UACSelfElvation von Microsoft beeinflusst. Wenn Sie mehr Details wünschen. Aber ich denke nicht, dass sie relevant sind.

Antwort

6

sieht hässlich aus, aber arbeiten kann:

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


Bearbeiten von John Gietzen:
Beweis:

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

+1

Bestätigte Arbeit. –

+1

Perfekt. Genau das habe ich gesucht. Es funktioniert, und obwohl es nicht schön ist, mit einem Kommentar, der den knapperen Weg zeigt und anzeigt, warum es hier nicht verwendet wurde, wird es großartig sein. Vielen Dank. Genau das habe ich mir bei Stackoverflow erhofft. – DanO

1

Die richtige Lösung wäre, vor dieser Zeile einen Kommentar hinzuzufügen, der besagt, dass die vom Tool erzeugte Warnung falsch ist. Dies verhindert, dass zukünftige Betreuer verwirrt werden und versuchen, etwas zu reparieren, das nicht kaputt ist.

+0

Wie behebt das sein Problem? –

+0

Kurz, um den Fehler in Resharper zu beheben, gibt es wirklich keine Lösung, oder? – cdhowie

+0

Nein, keine Lösung. Aber ein Workaround? könnte sein. Das ist, was er fragt. –

0

Ich stelle mir vor (wenn Sie wirklich, wirklich wollen) könnten Sie einen Schalter/Fall auf der Aufzählung verwenden. Aber meine Vermutung ist die Größe von dort ist aus einem Grund.

0

Wenn Sie daran interessiert sind, die Größe des zugrunde liegenden Datenobjekts der Enumeration zu erhalten, wäre es vielleicht ein besserer Weg, zuerst das System.Type-Objekt zu erhalten.

Type type = typeof (MyEnum); 
int enumSize = sizeof (Enum.GetUnderlyingType (type)); 
0

Sie es in ReSharper ignorieren können, aber es ist ein bisschen wie ein Schmerz und Kompromisse/ändert Ihr Design. Sie können die Enum-Definition und eine Methode, um die Größe (mit sizeof) in einer Klasse in einer eigenen Datei zu erhalten und klicken Sie auf ReSharper> Optionen ...> Code Inspektion> Einstellungen> Elemente zu überspringen und dann wählen Sie diese Datei (I verwende R # 5.1).

Offensichtlich erhalten Sie keine Code-Analyse, aber Sie erhalten immer noch das Code-Format Reinigung.