Domanda

Vorrei creare un metodo generico per convertire qualsiasi tipo derivato System.Enum al suo valore intero corrispondente, senza fusione e preferibilmente senza analizzare una stringa.

Per esempio, quello che voglio è qualcosa di simile:

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

Ma questo non sembra funzionare. ReSharper segnala che non puoi lanciare espressione di tipo 'System.Enum' di tipo 'int'.

Ora mi è venuta in mente questa soluzione, ma avrei preferito qualcosa di più efficiente.

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

Qualche suggerimento?

È stato utile?

Soluzione

Se non si vuole lanciare,

Convert.ToInt32()

potrebbe fare il trucco.

Il cast diretta (tramite (int)enumValue) non è possibile. Si noti che questo sarebbe anche "pericoloso", in quanto un enum può avere diversi tipi di fondo (int, long, byte ...).

Più formalmente: System.Enum non ha alcun rapporto diretto con l'eredità Int32 (anche se entrambi sono ValueTypes), in modo che il cast esplicito non può essere corretto all'interno del sistema di tipo

Altri suggerimenti

ho preso a lavorare per colata a un oggetto e poi a un int:

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

Questo è brutto e, probabilmente, non il modo migliore. Terrò pasticciano con esso, per vedere se riesco a venire con qualcosa di meglio ....

EDIT:. Stava per inviare che Convert.ToInt32 (EnumValue) funziona bene, e ho notato che MartinStettner mi ha battuto ad esso

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

Prova:

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

EDIT 2: Nei commenti, qualcuno ha detto che questo funziona solo in C # 3.0. Ho appena provato questo in VS2005 come questo e ha funzionato:

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));
    }

Se avete bisogno di convertire qualsiasi enum al tipo di fondo (non tutte le enumerazioni sono supportate da int), allora si può usare:

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

Perché avete bisogno di reinventare la ruota, con un metodo di supporto? E 'perfettamente legale per lanciare un valore enum al suo tipo di fondo.

E 'meno di battitura, e, a mio parere più leggibile, da usare ...

int x = (int)DayOfWeek.Tuesday;

... piuttosto che qualcosa di simile ...

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

Dalla mia risposta qui :

Dato e come in:

Enum e = Question.Role;

Poi questi lavori:

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);

Gli ultimi due sono semplicemente brutto. Il primo dovrebbe essere più leggibile, anche se il secondo è molto più veloce. O può essere un metodo di estensione è il migliore, meglio dei due mondi.

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;
}

Ora si può chiamare:

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

Casting da un System.Enum a un int funziona bene per me (è anche il MSDN ). Forse si tratta di un bug ReSharper.

Dal enumerazioni sono limitati al byte, sbyte, insomma, ushort, int, uint, lungo e ulong, possiamo fare alcune ipotesi.

Possiamo evitare eccezioni durante la conversione utilizzando il più grande contenitore di disposizione. Purtroppo, quale contenitore da utilizzare non è chiaro perché ulong farà saltare in aria per i numeri negativi e sarà lunga saltare in aria per i numeri tra long.MaxValue e ulong.MaxValue. Abbiamo bisogno di passare da queste scelte in base al tipo di fondo.

Naturalmente, è ancora necessario decidere cosa fare quando il risultato non si adatta all'interno di un int. Credo casting è a posto, ma ci sono ancora alcune cose da sapere:

  1. per le enumerazioni basato su un tipo con uno spazio di campo più grande di int (lungo e ulong), è possibile alcune enumerazioni valuteranno lo stesso valore.
  2. Casting un numero maggiore di int.MaxValue sarà un'eccezione se ci si trova in una regione controllata.

Ecco il mio suggerimento, lascio al lettore di decidere dove esporre questa funzione; come un aiutante o un'estensione.

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

Non dimenticate che il tipo Enum in sé ha un sacco di funzioni di supporto statiche in esso. Se tutto quello che vogliamo fare è di convertire un'istanza della enum al suo corrispondente tipo intero, poi la fusione è probabilmente il modo più efficiente.

Credo che ReSharper si lamenta perché Enum non è un'enumerazione di qualsiasi tipo particolare e enumerazioni stessi derivare da un ValueType scalare, non Enum. Se avete bisogno di colata adattabili in modo generico, direi che questo potrebbe Suite È bene (si noti che il tipo di enumerazione in sé è anche incluso nel generico:

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

Questo potrebbe quindi essere utilizzato in questo modo:

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

// ...

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

Non posso dire per certo fuori dalla parte superiore della mia testa, ma il codice di cui sopra potrebbe anche essere supportata da inferenza di tipo C # 's, permettendo il seguente:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top