daweed80
Messages postés3Date d'inscriptionmardi 12 février 2008StatutMembreDernière intervention27 avril 2009
-
27 avril 2009 à 17:02
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 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.
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 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 ! -
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 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 ! -
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 ! -
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 201361 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 ?
sebmafate
Messages postés4936Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention14 février 201437 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) :
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 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 ! -
sebmafate
Messages postés4936Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention14 février 201437 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); } }
}
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 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 ! -
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 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 ! -
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 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 ! -
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 201361 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......