Je code avec un modèle d'état pour un périphérique intégré. J'ai une classe de base / abstraite appelée État, puis chaque classe d'état discrète (concrète) implémente la classe d'État abstraite.
Dans la classe d'état, j'ai plusieurs méthodes abstraites. Si je n'implémente pas les méthodes abstraites dans la classe discrète (concrète), Visual Studio donnera une erreur quelque chose comme ceci:
... Erreur 1 'myConcreteState' n'implémente pas le membre abstrait hérité 'myAbstractState'
Maintenant: j'essaie de créer une propriété String pour chaque État appelé StateName. Chaque fois que je crée une nouvelle classe concrète, je dois définir StateName. Je veux que VS génère une erreur si je ne l'utilise pas. Existe-t-il un moyen simple de procéder?
J'ai essayé cela dans la classe abstract / base:
public abstract string StateName { get; set; }
Mais je n'ai pas besoin d'implémenter les méthodes Get et Set dans chaque état.
Question révisée: Dans une situation idéale, chaque classe d'état aurait besoin que StateName définisse et soit héritée de la classe de base abstraite.
StateName = "MyState1"; //or whatever the state's name is
Si cette instruction est manquante, Visual Studio générera une erreur comme décrit ci-dessus. Est-ce possible, et si oui comment?
Réponses:
Je suppose que la façon "correcte" de le faire est d'avoir un constructeur protégé sur la classe de base qui nécessite le nom de l'état comme paramètre.
Les états concrets fournissent alors un constructeur public qui appelle implicitement le constructeur de la classe de base avec le nom approprié.
Puisque la classe de base n'expose aucun autre constructeur (ni protégé ni public), chaque classe héritée doit passer par ce constructeur unique et doit donc définir un nom.
Notez que vous n'avez pas besoin de fournir le nom lorsque vous instanciez un état concret car son constructeur s'en charge:
la source
...:base(arg1, arg2)
! C'est une solution que je cherchais. Cela aide vraiment à garder mon codage d'État plus cohérent.À partir de C # 6 (je crois - C #: le nouveau et amélioré C # 6.0 ), vous pouvez créer des propriétés getter uniquement. Vous pouvez donc déclarer votre classe de base comme ceci -
Et puis dans votre sous-classe, vous pouvez implémenter
State
comme ça -Ou encore plus net en utilisant l'opérateur lambda -
Les deux renverraient toujours "State_1" et seraient immuables.
la source
public override string name { get; } = "State_1";
qui n'a alors pas besoin de réévaluer la valeur à chaque fois.Vos exigences sont une contradiction:
contre.
Il n'y a pas de fonction de langue qui vous permet de forcer l'existence d'un membre dans seulement quelques sous-classes. Après tout, l'intérêt d'utiliser une super classe est de s'appuyer sur le fait que toutes les sous-classes auront tous les membres de la super classe (et éventuellement plus). Si vous voulez créer des classes qui agissent comme un
State
mais qui n'ont pas de nom, alors par définition, elles ne doivent pas (/ peuvent) être des sous-classes deState
.Vous devez soit modifier vos besoins, soit utiliser autre chose qu'un simple héritage.
Une solution possible avec le code tel qu'il est pourrait être de rendre la méthode
State
non abstraite et de renvoyer une chaîne vide.la source
StateName = "MyState1"
dans chaque état. Si je n'ai pas cette instruction dans la classe d'état, alors, idéalement, Visual Studio générera une erreur.return "MyState1"
leur implémentation et peut ajouter un stockage modifiable pour la valeur si elle en a besoin. Mais vous devez clarifier les exigences de la question - chaque type d'état nécessite-t-il un StateName qui peut être lu, et tout type d'état nécessite-t-il une mutation après sa création?