Frage

ich mag ein gattungsgemäßes Verfahren schaffen für jeden System.Enum abgeleiteten Typen zu seinem entsprechenden ganzzahligen Wert umzuwandeln, ohne Gießen und vorzugsweise ohne einen Zeichenfolge Parsen.

Zum Beispiel, was ich will, ist so etwas wie folgt aus:

// Trivial example, not actually what I'm doing.
class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        (int)anEnum;
    }
}

Aber das scheint nicht zu funktionieren. ReSharper berichtet, dass Sie nicht Ausdruck des Typs werfen kann ‚System.Enum‘ ‚int‘ eingeben.

Jetzt habe ich mit dieser Lösung zu kommen, aber ich würde lieber etwas effizienter habe.

class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        return int.Parse(anEnum.ToString("d"));
    }
}

Irgendwelche Vorschläge?

War es hilfreich?

Lösung

Wenn Sie nicht wollen, werfen,

Convert.ToInt32()

konnte den Trick.

Die direkte Besetzung (via (int)enumValue) ist nicht möglich. Beachten Sie, dass dies auch „gefährlich“ wäre da eine Enumeration verschiedene zugrunde liegende Typen haben kann (int, long, byte ...).

Formal: System.Enum hat keine direkte Vererbungsbeziehung mit Int32 (obwohl beide sind ValueTypes), so dass die explizite Umwandlung kann innerhalb des Typ-Systems nicht richtig sein

Andere Tipps

habe ich es durch Gießen auf ein Objekt zu arbeiten und dann in einen int:

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return (int)((object)enumValue);
    }
}

Das ist hässlich und wahrscheinlich nicht der beste Weg. Ich werde mit ihm halten Unordnung, um zu sehen, ob ich etwas einfallen besser ....

EDIT:. War nur um zu schreiben, dass Convert.ToInt32 (EnumValue) funktioniert auch, und bemerkte, dass MartinStettner mich schlagen, um es

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

Test:

int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday

EDIT 2: In den Kommentaren, sagte jemand, dass dies nur C # 3.0 arbeitet. Getestet habe ich gerade dies in VS2005 so und es hat funktioniert:

public static class Helpers
{
    public static int ToInt(Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

    static void Main(string[] args)
    {
        Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
    }

Wenn Sie konvertieren jeder Enum zu dem zugrunde liegenden Typ (nicht alle Aufzählungen von int gesichert werden), dann können Sie:

return System.Convert.ChangeType(
    enumValue,
    Enum.GetUnderlyingType(enumValue.GetType()));

Warum müssen Sie das Rad mit einer Helfer-Methode neu zu erfinden? Es ist völlig legal einen enum Wert des zugrunde liegenden Typen zu werfen.

Es ist weniger tippen, und meiner Meinung nach besser lesbar zu verwenden ...

int x = (int)DayOfWeek.Tuesday;

... und nicht so etwas wie ...

int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();

Aus meiner Antwort hier :

Bei e wie in:

Enum e = Question.Role;

Dann wird diese Arbeit:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

Die letzten beiden sind nur hässlich. Die erste sollte besser lesbar sein, obwohl die zweite viel schneller ist. Oder kann eine Verlängerung Methode ist die beste, beste aus beiden Welten.

public static int GetIntValue(this Enum e)
{
    return e.GetValue<int>();
}

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
    return (T)(object)e;
}

Jetzt können Sie anrufen:

e.GetValue<int>(); //or
e.GetIntValue();

Die Giessen aus dem System.Enum zu einem int funktioniert gut für mich (es ist auch auf dem MSDN ). Vielleicht ist es ein ReSharper Fehler.

Da Aufzählungen auf Byte beschränkt sind, sbyte, kurz, ushort, int, uint, lang und ulong, können wir einige Annahmen getroffen werden.

Wir können mit Hilfe der größten verfügbaren Container Ausnahmen bei der Konvertierung vermeiden. Leider, die Behälter zu verwenden ist nicht klar, weil ulong für negative Zahlen sprengen wird und lange für Zahlen zwischen long.MaxValue und ulong.MaxValue sprengen. Wir müssen zwischen diesen Wahlen auf dem zugrunde liegenden Typ basiert wechseln.

Natürlich müssen Sie noch entscheiden, was zu tun ist, wenn das Ergebnis nicht innerhalb eines int paßt. Ich denke, Casting ist in Ordnung, aber es gibt noch einige gotchas:

  1. für Aufzählungen basierend auf einem Typ mit einem Feldraum größer als int (long und ulong), ist es möglich, einige Aufzählungen auf den gleichen Wert bewerten werden.
  2. eine Zahl größer als int.MaxValue Gießen wird eine Ausnahme ausgelöst, wenn Sie in einer überprüften Region sind.

Hier ist mein Vorschlag, ich es dem Leser überlassen werden, zu entscheiden, wo diese Funktion zu exponieren; als Helfer oder eine Erweiterung.

public int ToInt(Enum e)
{
  unchecked
  {
    if (e.GetTypeCode() == TypeCode.UInt64)
      return (int)Convert.ToUInt64(e);
    else
      return (int)Convert.ToInt64(e);
  }
}

Sie nicht vergessen, dass der Enum-Typ selbst eine Reihe von statischen Hilfsfunktionen in sich hat. Wenn alles, was Sie tun möchten, ist eine Instanz der Enumeration zu seinem entsprechenden Integer-Typ umwandeln, dann Gießen ist wahrscheinlich die effizienteste Art und Weise.

Ich denke, ReSharper beschwert, weil Enum nicht eine Aufzählung von einem bestimmten Typ ist und Aufzählungen sich ableiten von einem skalaren Valuetype, nicht Enum. Wenn Sie anpassungsfähig Gießen in allgemeiner Weise benötigen, würde ich sagen, das Sie gut Hotel könnte (beachten Sie, dass die Aufzählungstyp selbst auch in der allgemeinen enthalten ist:

public static EnumHelpers
{
    public static T Convert<T, E>(E enumValue)
    {
        return (T)enumValue;
    }
}

Dies könnte dann wie so verwendet werden:

public enum StopLight: int
{
    Red = 1,
    Yellow = 2,
    Green = 3
}

// ...

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);

Ich kann nicht sicher sagen, aus der Spitze von meinem Kopf, aber der obige Code könnte sogar von C # 's Typinferenz unterstützt werden, so dass die folgenden:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top