comment puis-je utiliser la déclaration de commutateur sur le modèle de type-safe enum

J’ai trouvé un exemple intéressant sur l’énumération de la mise en œuvre d’une manière différente. C’est ce qu’on appelle un modèle de type-safe enum, je pense. J’ai commencé à l’utiliser mais je me suis rendu compte que je ne pouvais pas l’utiliser dans une instruction switch.
Mon implémentation ressemble à ceci:

public sealed class MyState { private readonly ssortingng m_Name; private readonly int m_Value; public static readonly MyState PASSED= new MyState(1, "OK"); public static readonly MyState FAILED= new MyState(2, "ERROR"); private MyState(int value, ssortingng name) { m_Name = name; m_Value = value; } public override ssortingng ToSsortingng() { return m_Name; } public int GetIntValue() { return m_Value; } } 

Que puis-je append à ma classe pour pouvoir utiliser ce modèle dans les instructions de commutateur en C #?
Merci.

Vous pouvez essayer quelque chose comme ça:

 class Program { static void Main(ssortingng[] args) { Gender gender = Gender.Unknown; switch (gender) { case Gender.Enum.Male: break; case Gender.Enum.Female: break; case Gender.Enum.Unknown: break; } } } public class Gender : NameValue { private Gender(int value, ssortingng name) : base(value, name) { } public static readonly Gender Unknown = new Gender(Enum.Unknown, "Unknown"); public static readonly Gender Male = new Gender(Enum.Male, "Male"); public static readonly Gender Female = new Gender(Enum.Female, "Female"); public class Enum { public const int Unknown = -1; public const int Male = 1; public const int Female = 2; } } public abstract class NameValue { private readonly int _value; private readonly ssortingng _name; protected NameValue(int value, ssortingng name) { _value = value; _name = name; } public int Value { get { return _value; } } public ssortingng Name { get { return _name; } } public override ssortingng ToSsortingng() { return Name; } public override int GetHashCode() { return Value.GetHashCode(); } public override bool Equals(object obj) { NameValue other = obj as NameValue; if (ReferenceEquals(other, null)) return false; return this.Value == other.Value; } public static implicit operator int(NameValue nameValue) { return nameValue.Value; } } 

Le modèle enum typ-safe est intéressant car vous pouvez append un comportement à des membres individuels enum (qui sont des instances). Donc, si le comportement que vous voulez activer pourrait faire partie de la classe, utilisez simplement le polymorphism. Notez que vous devrez peut-être créer des sous-classes pour chaque membre qui redéfinit le comportement:

 public class MyState { public static readonly MyState Passed = new MyStatePassed(); public static readonly MyState Failed = new MyStateFailed(); public virtual void SomeLogic() { // default logic, or make it abstract } class MyStatePassed : MyState { public MyStatePassed() : base(1, "OK") { } } class MyStateFailed : MyState { public MyStateFailed() : base(2, "Error") { } public override void SomeLogic() { // Error specific logic! } } ... } 

Usage:

 MyState state = ... state.someLogic(); 

Maintenant, si la logique n’appartient clairement pas et que vous voulez vraiment changer de poste, mon conseil est de créer un enum frère:

 public enum MyStateValue { Passed = 1, Failed = 2 } public sealed class MyState { public static readonly MyState Passed = new MyState(MyStateValue.Passed, "OK"); public static readonly MyState Failed = new MyState(MyStateValue.Failed, "Error"); public MyStateValue Value { get; private set; } private MyState(MyStateValue value, ssortingng name) { ... } } 

Et allumez ça:

 switch (state.Value) { case MyStateValue.Passed: ... case MyStateValue.Failed: ... } 

Dans ce cas, si la classe enum-safe-type n’a pas de comportement, il n’y a pas beaucoup de raison pour qu’elle existe à la place de l’énum elle-même. Mais bien sûr, vous pouvez avoir la logique et un enum en même temps.

Jordão a la bonne idée, mais il existe un meilleur moyen de mettre en œuvre le polymorphism, utilisez délégué .

L’utilisation de delegates est plus rapide qu’une instruction switch. (En fait, je suis convaincu que le seul endroit pour les instructions switch dans le développement orienté object est une méthode d’usine. Je recherche toujours une sorte de polymorphism pour remplacer les instructions switch dans les codes que je traite.)

Par exemple, si vous souhaitez un comportement spécifique basé sur un type-safe-enum, le modèle suivant correspond à ce que j’utilise:

 public sealed class EnumExample { #region Delegate definitions ///  /// This is an example of adding a method to the enum. /// This delegate provides the signature of the method. ///  /// A parameter for the delegate /// Specifies the return value, in this case a (possibly /// different) EnumExample private delegate EnumExample DoAction(ssortingng input); #endregion #region Enum instances ///  /// Description of the element /// The static readonly makes sure that there is only one immutable /// instance of each. ///  public static readonly EnumExample FIRST = new EnumExample(1, "Name of first value", delegate(ssortingng input) { // do something with input to figure out what state comes next return result; } ); ... #endregion #region Private members ///  /// The ssortingng name of the enum ///  private readonly ssortingng name; ///  /// The integer ID of the enum ///  private readonly int value; ///  /// The method that is used to execute Act for this instance ///  private readonly DoAction action; #endregion #region Constructors ///  /// This constructor uses the default value for the action method /// /// Note all constructors are private to prevent creation of instances /// by any other code ///  /// integer id for the enum /// ssortingng value for the enum private EnumExample(int value, ssortingng name) : this (value, name, defaultAction) { } ///  /// This constructor sets all the values for a single instance. /// All constructors should end up calling this one. ///  /// the integer ID for the enum /// the ssortingng value of the enum /// the method used to Act private EnumExample(int value, ssortingng name, DoAction action) { this.name = name; this.value = value; this.action = action; } #endregion #region Default actions ///  /// This is the default action for the DoAction delegate ///  /// The inpute for the action /// The next Enum after the action static private EnumExample defaultAction(ssortingng input) { return FIRST; } #endregion ... }