7
votes

Définissez une énorme valeur par défaut

Je suis sûr que c'est assez trivial mais je ne peux pas le faire correctement. XXX

La ligne Valeur = Par défaut (valeur.getype ()); Ne compile pas, mais j'espère que vous pourrez voir ce que je tente. J'ai besoin de définir l'ENUM PARAM sur la valeur par défaut de son propre type.


10 commentaires

Comment pouvez-vous même appeler cette méthode sans la «valeur» définie dans l'énum du même type que la «valeur»?


@Paw, c'est la façon dont Enum fonctionne. Vous pouvez stocker n'importe quelle valeur INT dans un Int Enum, que ce soit défini ou non.


@farofawhackplanet, j'essaie simplement de comprendre ce que vous essayez de faire. Si vous voulez convertir un Int enum ou peut-être une chaîne à un énumé?


Non, je interrogee le Fieldinfo sur l'énum, ​​qui jette évidemment une exception si l'énumé n'est pas défini. Il est logique que je pense utiliser le champ «défaut »Info dans ce cas.


... Et la raison pour laquelle la valeur Enum pourrait ne pas être définie est que notre base de données est pleine de merde malheureusement :)


C'est en fait une question très intéressante. Malheureusement, la plupart des réponses ont apparemment compris la tâche. Cela aurait peut-être contribué à choisir un nom meilleur que DOSOMODING .


@Konrad, point pris. Pour des raisons évidentes, j'essaie de poster des exemples simplifiés qui obtiennent l'objectif exact du code, et cela entraîne souvent mal que les gens malentent ou me disent que ce que je fais ne donne aucun sens. J'aurais peut-être pu donner un peu plus de détails ici, mais je pensais que le problème spécifique était assez apparent de l'exemple.


Je pense que vous pouvez envisager une "valeur par défaut" pour signifier quelque chose de différent de ce que le compilateur utilisera comme défaut pour les énumérations. La valeur par défaut d'une énumération est toujours nulle, même s'il n'y a pas de valeur zéro définie dans votre énum. De la spécification "La valeur par défaut d'un ENum E est la valeur produite par l'expression (E) 0."


HMMM, relecture de la question, peut-être que j'ai mal compris.


@farrofawhackplanet - Je ne suis pas sûr que vous posiez la bonne question ici. Certaines des réponses fournies vous donnent une énumération par défaut (avec valeur 0) conformément aux règles CLR qui peuvent ou non être une énumération définie - vous laissant ainsi dans le même bateau qu'auparavant. Je dirais que la "valeur par défaut" que vous voulez est vraiment une valeur énumérée définie arbitrairement qui diffère pour chaque définition d'énumération. Donc, soit vous devez décorer votre définition Enum pour marquer cette valeur spéciale ou vous devez transmettre cette valeur spéciale dans votre routine DOIOMIATQUEH. En effet, le système CLR ne connaît pas votre intention


5 Réponses :


1
votes

Activator.CreateInstance (typeof (consolecolor)) semble fonctionner


3 commentaires

Vous avez besoin d'une fonte dure pour cela. (Consolecolor) Activator.createInstance (typeof (consolecolor))


@Paw, comment feriez-vous cela dans l'exemple de la peur (avec un type dynamique)


Vous ne pouvez pas, c'est pourquoi je ne pense pas que cela fonctionnera avec l'activateur.



-1
votes

Enum par défaut a sa valeur première valeur comme valeur par défaut


2 commentaires

Encore une fois, comment cela résoudra-t-il mon problème? (Et ce n'est même pas techniquement correct, je ne pense pas)


-1: Désolé, mais la valeur par défaut de chaque énum est 0, même si 0 est une valeur non valide pour l'énum. Essayez enum myenum {m1 = -1, m2 = 1}; Myenum e = défaut (myenum); ... console.writeline ("{0}", e); écrit 0



-1
votes

Avez-vous pensé à en faire une méthode générique?

public static string DoSomething<T>(Enum value)
{
    if (!Enum.IsDefined(typeof(T), value))
    {
        value = (T)Enum.ToObject(typeof(T), 0);
    }
    // ... do some other stuff
}


4 commentaires

Le où T: Enum n'existe pas dans C #. :-( C'est tout le problème ici.


Travaillerait encore, sans le "où". Vous auriez juste besoin d'essayer / attraper pour vous assurer que votre casser ne fait pas exploser. Je jetterais une nouvelle exception à l'appelant si t n'était pas un énumé.


Donc, s'il ne sait pas ce que le type Enum est, comment déclarent-il?


@Caspar, eeh, c'est pourquoi j'ai écrit "l'appelant de la méthode doit connaître le type". Si l'appelant ne peut pas alors cela ne fonctionnera pas.



5
votes

Je ne suis pas vraiment sûr de ce que vous essayez de faire ici, mais une version de la ligne 'Par défaut' qui compilise est la suivante:

 value = (Enum) Enum.ToObject(value.GetType(), 0);


6 commentaires

ou valeur = (Enum) Enum.toObject (valeur.getType (), 0);


@ Paw Que si vous utilisez ceci: Enum foo {A = 1, b = 2} ? +1 à volonté, ça a l'air assez robuste


@Paw: Non. 0 n'est pas une valeur définie pour tous les énumérums.


@Konrad: Cela pourrait être le cas, mais 0 est la valeur par défaut pour une énumération, qu'il soit défini ou non. C'est ce que le compilateur initialise les variables ENum à et l'une des raisons pour lesquelles il existe une erreur FXCOP concernant une valeur zéro dans les définitions ENUM. À partir de la spécification ", la valeur par défaut d'un ENum E est la valeur produite par l'expression (E) 0."


@Konrad: Je ne suis pas si sûr. Ils ne connaissent pas le type d'énumération et il suffit de définir la valeur à zéro ne fonctionnerait pas sans couler, mais ils ne peuvent pas se lancer parce qu'ils n'ont pas le type.


@Jeff, oui c'est correct. Il serait plus frais de le faire la méthode «appropriée», mais dans mon cas, je ne me soucie pas trop que toutes mes énumes ont un Nottset = 0 de toute façon. Je suis resté coincé parce que valeur = 0 ne fonctionne pas sans couler comme vous l'avez commenté.



2
votes

Vous pouvez réellement faire ce que Paw suggère a >, même avec une contrainte générique, si vous pouviez déplacer cette méthode à sa propre classe: xxx pré>

alors vous feriez, par exemple: p> xxx pré>

Comme Konrad Rudolph souligne dans un commentaire, par défaut (tenum) code> dans le code ci-dessus évaluera à 0, que la valeur soit définie ou non pour 0 pour le Tenum code> type. Si ce n'est pas ce que vous voulez, Réponse de Will fournit certainement le moyen le plus simple d'obtenir la première valeur définie em> ( (tenum) enum.getvalues ​​(typeof (tenum)). GetValue (0) code>). P>

D'autre part, si vous voulez prendre cela à la extrême forte> et cache le résultat de sorte que vous n'ayez pas toujours à la boîte, vous pourriez le faire: P>

public abstract class Helper<T>
{
    static Dictionary<Type, T> s_defaults = new Dictionary<Type, T>();

    public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T
    {
        if (!Enum.IsDefined(typeof(TEnum), value))
        {
            value = GetDefault<TEnum>();
        }

        // ... do some other stuff

        // just to get code to compile
        return value.ToString();
    }

    public static TEnum GetDefault<TEnum>() where TEnum : struct, T
    {
        T definedDefault;
        if (!s_defaults.TryGetValue(typeof(TEnum), out definedDefault))
        {
            // This is the only time you'll have to box the defined default.
            definedDefault = (T)Enum.GetValues(typeof(TEnum)).GetValue(0);
            s_defaults[typeof(TEnum)] = definedDefault;
        }

        // Every subsequent call to GetDefault on the same TEnum type
        // will unbox the same object.
        return (TEnum)definedDefault;
    }
}


3 commentaires

@Konrad: que peut être parce que j'avais une faute de frappe ( tenumvalue -NOO espace). De plus, je n'ai pas inclus de valeur de retour. Je serais curieux de savoir si cela compilait pour Mono maintenant que j'ai mis à jour l'exemple.


Je serais déjà corrigé cela, n'a pasidé. Bizarre, il compile maintenant (+1, élégant hack!) - mais il a le même problème que les autres solutions, à savoir que par défaut retourne vraiment 0 qui peut être un indéfini. valeur dans l'énumération réelle et n'est donc pas le bon résultat. Il y a le problème supplémentaire que votre solution ne fonctionne plus comme une méthode d'extension.


@Konrad: Ouais, j'ai réalisé que trop peu de temps après avoir posté (testé sur un énumé dont la première valeur définie est 1), mais je sentais que cela valait la peine de mentionner depuis qu'il semble une de choses que l'OP essayait de faire était simplement écrire par défaut (tenum) .