Cette question concerne le casting d'énums au sein de méthodes génériques
Donné un enum
public enum Crustaceans
{
Frog = 1,
Toad = 4
}
Je peux créer assez simplement une instance de mon enum
short val = 4;
Crustaceans crusty = (Crustaceans) val;
Toutefois, si
short val = 4;
object obj = (object) val;
Crustaceans crusty = (Crustaceans)obj;
une exception d'exécution est levée alors qu'elle tente d'exécuter l'initialisation de Crusty.
Quelqu'un peut-il expliquer pourquoi cela se produit et pourquoi ce n'est pas légal de faire une telle chose.
Non pas que je veuille vraiment faire cela, mais je me suis heurté à un problème lorsque j'essayais de faire quelque chose de similaire avec les génériques et que c’est effectivement ce qui se passe sous la couverture. c'est à dire.
public T dosomething<T>(short val) where T : new()
{
T result = (T)(object) val;
return result;
}
Donc, ce que je tente de faire est d’avoir une fonction générique qui fonctionne avec des énumérations et des non-énumérations (pas si critique mais qui serait Nice) qui peut être définie sur une valeur courte sans lever d’exception ni initialiser la valeur d’énum correcte.
Quelque chose comme ceci probablement vous aidera à:
public T dosomething<T>(object o)
{
T enumVal= (T)Enum.Parse(typeof(T), o.ToString());
return enumVal;
}
Mais cela fonctionnera seulement avec des enums, pour une raison claire d'utiliser Enum.Parse(..)
Et utilisez ceci comme, par exemple:
object o = 4;
dosomething<Crustaceans>(o);
Cela renverra Toad
dans votre cas.
Il existe des cas où vous ne pouvez pas utiliser les génériques (comme dans un convertisseur WPF lorsque vous obtenez la valeur sous la forme object
) . Dans ce cas, vous ne pouvez pas transtyper en int
car le type enum peut ne pas être int
. C'est une manière générale de le faire sans Génériques . L'exemple est donné à l'intérieur d'un convertisseur WPF, mais le code qu'il contient est général:
using System;
using System.Windows;
using System.Windows.Data;
.
.
.
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var enumType = value.GetType();
var underlyingType = Enum.GetUnderlyingType(enumType);
var numericValue = System.Convert.ChangeType(value, underlyingType);
return numericValue;
}
Dans le cas des types intégraux encadrés en tant qu'objets, la méthode correcte pour convertir est d'utiliser Enum.ToObject method:
public T Convert<T>(object o)
{
T enumVal= (T)Enum.ToObject(typeof(T), o);
return enumVal;
}
Par défaut, les valeurs numériques enum ont le type = int. Dans votre code, vous souhaitez transtyper des valeurs de type court en type enum. Pour cela, vous devez définir le type court à vos valeurs enum. Cela fonctionnera:
public enum Crustaceans : short // <--
{
Frog = 1,
Toad = 4
}
short @short = 1;
object @object = @short;
var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog
si vous ne voulez pas changer le type de valeurs enum par défaut
public enum Crustaceans
{
Frog = 1,
Toad = 4
}
object @object = Crustaceans.Frog;
var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog
ou
public enum Crustaceans
{
Frog = 1,
Toad = 4
}
int @integer= 1;
var @enum = (Crustaceans)@integer; // @enum = Crustaceans.Frog