Dériver un énuméré

Résolu
daweed80 Messages postés 3 Date d'inscription mardi 12 février 2008 Statut Membre Dernière intervention 27 avril 2009 - 27 avril 2009 à 17:02
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 - 28 avril 2009 à 12:57
Bonjour à tous,

J'aurais besoin de dériver un énuméré.
En fait dans l'énuméré fille il faut que j'ai accès aux "attributs" de l'énuméré mère.

Si j'ai
       

publicenum EnumMere
{
Un = 1,
Deux = 2,
Trois = 3
}

publicenum EnumFille
{
Quatre = 4,
Cinq = 5
}

je voudrais pouvoir faire ça par exemple :
EnumFille.Un

Je ne sais pas si je suis très clair, n'hésitez pas à demander des précisions.

18 réponses

cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
27 avril 2009 à 18:13
Grrr,
je reposte pour la gestion des espaces !!!!

public
class Mere
{

public 
static 
readonly 
int  Un = 1;

public 
static 
readonly 
int  Deux = 2;

public 
static 
readonly 
int  Trois = 3;
}

public
class Fille : Mere
{

public 
static 
readonly 
int  Quatre = 4;

public 
static 
readonly 
int  Cinq = 5;
}

C# is amazing, enjoy it!
3
daweed80 Messages postés 3 Date d'inscription mardi 12 février 2008 Statut Membre Dernière intervention 27 avril 2009
27 avril 2009 à 18:53
C'est exactement ce que j'ai trouvé comme solution et ca à l'air de convenir à tous les besoins du projet.

Merci quand même a vous pour votre rapidité ;)

A bientot ici:
3
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
27 avril 2009 à 17:51
Salut

A ma connaissance ce n'est pas possible.
Une alternative que je vois serait d'utiliser des membres static en lecture seule (ou une propriété, ça revient au même)

    public class Mere
    {
        protected int val;
        protected Mere(int i)
        {
            val = i;
        }

        public int Val
        {
            get { return val; }
        }

        public static readonly Mere Un = new Mere(1);
        public static readonly Mere Deux = new Mere(2);
        public static readonly Mere Trois = new Mere(3);
    }

    public class Fille : Mere
    {
        protected Fille(int i) : base(i) { }

        public static readonly Fille Quatre = new Fille(4);
        public static readonly Fille Cinq = new Fille(5);
    }

Bon, je te l'accorde, c'est plus long. Mais après, tu peux utiliser la classe Mere pour 1 à 3 et la classe Fille pour 1 à 5 (utilise la propriété Val de ton objet pour récupérer sa valeur)

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
27 avril 2009 à 18:11
Bonsoir,

Je suis d'accord avec Krimog,

mais pourquoi pas plus simplement:      publicclass Mere<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>

      {

            publicstaticreadonlyint Un = 1;

            publicstaticreadonlyint Deux = 2;

            publicstaticreadonlyint Trois = 3;

      }

 

      publicclass Fille : Mere

      {

            publicstaticreadonlyint Quatre = 4;

            publicstaticreadonlyint Cinq = 5;

      }

?
C# is amazing, enjoy it!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
27 avril 2009 à 18:31
J'y ai pensé à la base, mais c'est pour éviter les choix non valides.

private void MaMethode(int val);
=> MaMethode(Mere.Un); // ça marche
=> MaMethode(Fille.Deux); // ça marche
=> MaMethode(50); // ça marche alors que ça ne devrait pas

avec ma méthode :
private void MaMethode(Mere val);
=> MaMethode(Mere.Un); // ça marche
> MaMethode(Fille.Deux); // > Impossible de caster un Fille en Mere (enfin je crois, pas testé)
> MaMethode(50); // > Impossible de caster un int en Mere.

private void MaMethode(Fille val);

=> MaMethode(Mere.Un); // ça marche

=> MaMethode(Fille.Deux); // ça marche

> MaMethode(50); // > Impossible de caster un int en Mere

voilà la raison ;)

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
27 avril 2009 à 18:36
Ah mince, c'est dans l'autre sens que ça ne marche pas :

private void MaMethode(Mere val);
=> MaMethode(Fille.Deux); // marche

private void MaMethode(Fille val);
=> MaMethode(Mere.Un); // marche pas

Le fait que ça ne marche pas pour la deuxième solution n'est pas problématique
Cependant, le fait que ça marche pour la première l'est plus...
A part en faisant une vérification de type de val dans MaMethode, je ne vois pas comment éviter ça...
Ouvert aux suggestions ;)

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
27 avril 2009 à 21:42
En C#, les values-type ne peuvent pas être dérivés.
Cela dit, il faut plutôt se poser la question s'il n'y a pas un problème de conception là derrière ?

<hr />
-Blog-
-Site Perso-
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
28 avril 2009 à 08:31
humm... comme le dit bidou, il n'est pas possible de dériver des types valeurs en .net.

Par contre, tu peux résoudre ton problème en utilisant une struct plutot qu'une classe. Un bon exemple : étudie la façon dont sont implémentées les struct Color et Colors.

Enfin, il est important de comprendre qu'une enum n'évite pas de passer n'importe quelle valeur à une méthode.
Par exemple le code suivant est parfaitement valable (et compile) :

public enum MonEnum {
Zero : 0,
Un,
Deux,
Trois
}

public void MaMethod(MonEnum value) { ... }

MaMethod((MonEnum)50);
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
28 avril 2009 à 09:52
A ceci près que là tu vois que tu utilises un comportement potentiellement risqué, puisque tu es obligé de faire un cast alors qu'un gentil enum est fait pour toi.

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
28 avril 2009 à 10:07
Il n'y a rien de risqué, le cast est toujours valide.

<hr />
-Blog-
-Site Perso-
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
28 avril 2009 à 10:12
Biensûr que c'est risqué... mais ça marche !

En fait, le problème avec la réponse de Robert33 que tu as validé c'est qu'elle n'évite pas de passer n'importe quelle valeur... puisqu'en réalité ta méthode a besoin d'un _int_.
C'est pourquoi je t'ai conseillé de regarder le fonctionnement de Color.

struct Color {
public byte A;
public byte R;
public byte G;
public byte B;

public Color (byte a, byte r, byte g, byte b) {
this.A = a;
this.R = r;
this.G = g;
this.B = b;
}

public static Color Red { get { return new Color(255,255,0,0); } }
public static Color Blue{ get { return new Color(255,0,0,255); } }
public static Color Green{ get { return new Color(255,0,255,0); } }
}

Donc, s'il l'on applique à ton exemple, ça donne :

public struct Mere {
public int MaValeur;
public Mere(int maValeur) {
this.MaValeur = maValeur;
}

public static Un { get { return new Mere(1); } }
public static Deux { get { return new Mere(2); } }
public static Trois { get { return new Mere(3); } }
}

public struct Fille : Mere {
public Fille(int valeur) : base(valeur) {}

public static Quatre { get { return new Fille(4); } }
public static Cinq{ get { return new Fille(5); } }
}
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
28 avril 2009 à 11:18
@Bidou : "Il n'y a rien de risqué, le cast est toujours valide." => Le cast est parfaitement valide, mais ce n'est pas pour autant que ça ne peut pas être à risque. Exemple :
enum monEnum
{
    machin = 1,
    truc = 2
}

int maMethode(monEnum m)
{
    return 10/(int)m;
}

=> si tu appelles maMethode((monEnum)0); il ne faudra pas te plaindre si ça plante. Et dans ce cas précis, je critiquerais plutôt la personne pour avoir appelé maMethode avec 0 que pour ne pas avoir blindé la maMethode. (Il est obligatoire de blinder l'interface utilisateur, car, de base, l'utilisateur est con, rappelons-le, mais un programmeur qui fait un cast pour pouvoir placer la valeur qu'il souhaite, selon moi, cherche un peu la merde :-) (et s'il met une variable à la place de l'entier, il peut très bien blinder l'appel à la méthode)).

@Sebmafate :
Tout d'abord, si mes souvenirs sont corrects, une structure ne peut pas hériter de quoique ce soit. A la limite, elle peut juste implémenter des interfaces. (De plus, tu as oublié de préciser le type des valeurs de retour de tes propriétés ;-), enfin, c'est pas le problème).
Ta méthode marche (à 2-3 détails près), cependant, elle ne blinde pas ni ne "décourage" le programmeur d'utiliser des valeurs imprévues. Sur ce point, mon code n'ayant pas de constructeur et une propriété en lecture seule, il ne permet pas de mettre n'importe quoi.
Cependant, il reste un défaut à ma méthode, c'est que l'on peut donner une valeur de fille lorsqu'on demande une mère (c'est d'ailleurs la raison de base de mon autre post).

Ceci dit, ce n'est que mon point de vue, qui n'est pas forcément le meilleur.

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
28 avril 2009 à 11:27
Pas vraiment, c'est de la responsabilité de la méthode qui prend l'enum en paramètre en principe.
Pour les guidlines des enums, voire: http://blogs.codes-sources.com/coq/archive/2009/02/20/une-num-ration-enum-en-c-num-re-mais-ne-donne-pas-de-garantie.aspx.

<hr />
-Blog-
-Site Perso-
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
28 avril 2009 à 11:36
C'est une question de point de vue.
Je suis d'accord que c'est toujours mieux de blinder, mais si on demande de manière très explicite à une programmeur de mettre un nombre en 1 et 10 et qu'il s'amuse à mettre 42...

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
28 avril 2009 à 11:43
Bof pas tellement, je suis persuadé que si tu avais un int à la place de l'enum, tu aurais fait quelques choses comme:

if(val == 0) throw new ArgumentException(...)
else
{
   double d = x/val
}

Etant donné que l'enum dérive de int..........

<hr />
-Blog-
-Site Perso-
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
28 avril 2009 à 12:46
C'est clair. J'aurais blindé si c'était un int. Cependant, je vois pas ce qui pourrait pousser quelqu'un à appeler la fonction avec une valeur qu'on ne propose pas. (L'esprit de contradiction ?)
Avez-vous un travail ? _ _ _ (forcément, "ça dépend" ça dépasse ^^) (je ne suis pas sûr de l'exactitude de la partie question de la citation cependant). Au final ça revient un peu au même.

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
28 avril 2009 à 12:48
Ah, j'ai retrouvé la citation exacte : "Exercez-vous une profession ? _ _ _"

Krimog : while (!(succeed = try())) ;
- NON, "LE BAR" n'est PAS un langage de programmation ! -
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
28 avril 2009 à 12:57
Et c'est bien là le problème qu'on soulève avec un enum...
Il n'est pas limité aux valeurs qu'il propose! C'est à dire que de mettre une autre valeur que celle de l'enum ne soulève aucune exception.
C'est la porte ouverte à toutes les failles que de ne pas faire les tests appropriés (sous prétexte qu'il peut seulement prendre logiquement un set de valeur prédéfini).
Et c'est justement la source de bons nombres de failles: mettre des valeurs qui n'était pas prévu par le programmeur......

<hr />
-Blog-
-Site Perso-
0
Rejoignez-nous