2
votes

EnumValue dans TypeConverter

J'ai une classe avec des propriétés telles que:

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
    var enumValue = Convert.ToInt32(value);
    return  (context.PropertyDescriptor.PropertyType) enumValue
}

Dans mon Enum TypeConverter, j'essaie d'obtenir le nom Enum à partir d'un certain entier, car la source lit une table composée de strings.

Dans le tableau, il est stocké comme par exemple "33" (donc pas le nom), par ex. de

public enum Example
{
    Off = 1,
    On = 33,
    Whatever = 7
}

Puis voici un morceau de mon code de convertisseur:

[TypeConverter(typeof(SomeNameEnumValueConvert))]
public Example ExampleName { get; set; }

Cependant, cela donne ici que le contexte est une variable, pas un type . J'ai donc essayé différentes façons de faire fonctionner cela, mais parallèlement à cela, je le posterai ici, peut-être que cela accélère les tentatives. J'ai essayé de convertir en Enum, de lancer en (enum) (objet), de lancer via GetType, de lancer via Assembly pour obtenir le type spécifique, mais rien de tout cela ne semble fonctionner. Ergo comment convertir le type de système sous-jacent.


15 commentaires

Je voulais savoir si je vous ai bien compris: vous voulez obtenir Example.off ou Example.On ou Example.Whatever selon la valeur sur enumValue ?


context.PropertyDescriptor.PropertyType est un objet Type . Vous ne pouvez pas convertir une valeur en un Type


@Code Pope: oui, j'ai lu un tableau avec des chaînes uniquement (paires clé / valeur) et j'ai un objet fortement typé. Dans cet objet fortement typé, j'ai une propriété enum. Cela doit donc être défini lors de la lecture du tableau. J'ai donc annoté cette propriété enum avec le convertisseur de types.


Voulez-vous obtenir une représentation sous forme de chaîne, c'est-à-dire: Off , ou On ou une valeur numérique telle que 1 ou 33 ou Voulez-vous aller à Enum à partir d'une représentation sous forme de chaîne?


Vous êtes après Enum.Parse ou Enum.TryParse


@ HasanEmrahSüngü Alors j'ai "3" qui arrive, comment puis-je utiliser Enum.Parse? Je pense que Enum.Parse est basé sur le type (qui est le problème) et la valeur.


@edelwater, "3" n'est pas défini dans vos exemples d'énumérations


Tant que la question est claire, prenez par exemple "33" au lieu de "3". Donc par exemple (context.PropertyDescriptor.PropertyType) .GetEnumValues ​​() fonctionnera mais pas (context.PropertyDescription.PropertyType) enumValue


Dans mon commentaire précédent, j'ai expliqué pourquoi vous NE POUVEZ PAS faire (context.PropertyDescription.PropertyType) enumvalue


return Enum.Parse (context.PropertyDescriptor.PropertyType, enumValue);


@Ian Kemp, le deuxième argument ici est une chaîne, j'ai "33", voir ci-dessus, mais je pense que votre indice sur ToObject va probablement quelque part.


@edelwater, beaucoup de gens suggèrent la même réponse mais vous dites que ce n'est pas correct. Pouvez-vous expliquer pourquoi la version suggérée ne fonctionne pas?


Il s'agit d'un convertisseur de type avec une valeur int entrante, TryParse a une chaîne comme deuxième paramètre avec le nom de l'enum spécifique et non la valeur assignée. ToObject a cette valeur mais renvoie la valeur Donc j'ai toujours besoin de ((context.PropertyDescription.PropertyType) enumvalue mais le (context.PropertyDescription.PropertyType) n'est pas le type correct.


@edelwater, vous NE POUVEZ PAS faire (context.PropertyDescription.PropertyType) enumValue . Pourquoi parce que (context.PropertyDescription.PropertyType) est un Type . Vous ne pouvez pas diffuser directement dans une instance de Type


@edelwater Enum.Parse prend une chaîne, mais cette chaîne peut être soit le champ enum comme "On", soit la valeur entière sous forme de chaîne, par exemple "33". Il ne devrait donc y avoir aucune différence entre Parse et ToObject dans votre cas, IMO. Mais content que vous l'ayez trié.


3 Réponses :


-1
votes

Essayez simplement ceci dans votre convertisseur:

Example expEnum = (Example)Enum.Parse(typeof(Example), value.ToString(), true);
return expEnum;


3 commentaires

Vous avez complètement ignoré ce que la question demandait juste pour poster une réponse générique «utiliser Enum.Parse» dans l'espoir de la réputation de l'agriculture.


@IanKemp il n'y a même pas de travail "générique" dans la question! ce n'est que votre opinion, laissez Edelwater en parler. Merci


typeof (Exemple) avec typeof (context.PropertyDescriptor.PropertyType) donne "variable mais utilisé comme un type", le deuxième paramètre est un int dans mon cas pas une chaîne?



2
votes

Pour obtenir le nom enum (par exemple "On") à partir de la valeur, vous pouvez utiliser Enum.GetName:

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
    var enumValue = Convert.ToInt32(value);
    return Enum.ToObject(context.PropertyDescriptor.PropertyType, enumValue);
}

Pour obtenir le membre enum (par exemple Example.On ) à partir de la valeur, utilisez Enum.ToObject :

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
    var enumValue = Convert.ToInt32(value);
    return Enum.GetName(context.PropertyDescriptor.PropertyType, enumValue);
}


1 commentaires

Merci, en effet Enum.ToObject était la voie à suivre.



1
votes

Vous pouvez essayer ceci si vous voulez une solution générique:

public static class Example
{
    enum Day { Sun, Mon, Tue, Wed, Thu, Fri, Sat };

    public static void Foo()
    {
        Day day = Day.Tue;
        int dayIndex = day.ToInt();
        // dayIndex = 2
        Day result = (dayIndex + 2).ToEnum<Day>();
        // result = Thu
    }

    public static int ToInt<T>(this T t) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumeration type");
        }
        return Convert.ToInt32(t);
    }

    public static T ToEnum<T>(this int i) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumeration type");
        }
        return (T)Enum.ToObject(typeof(T), i);
    }
}


0 commentaires