42 votes

C #, implémenter des méthodes de type 'résumé abstrait'

J'ai récemment rencontré un problème où il semble que j'ai besoin d'un " statique résumé de la méthode. Je sais pas pourquoi c'est impossible, mais comment puis-je contourner cette limitation?

Par exemple, j'ai une classe abstraite qui a une chaîne de description. Depuis cette chaîne est commun pour tous les cas, il est marqué comme statique, mais je veux exiger que toutes les classes dérivées de cette classe de fournir leur propre Description de la propriété, de sorte que j'ai marqué comme abstrait:

abstract class AbstractBase
{
    ...
    public static abstract string Description{get;}
    ...
}

Il ne compile pas, bien sûr. J'ai pensé à l'utilisation d'interfaces mais les interfaces ne peuvent pas contenir méthode statique signatures.

Devrais-je le faire tout simplement non-statique, et de toujours obtenir une instance pour obtenir la classe de l'information spécifique?

Des idées?

34voto

leppie Points 67289

Tu ne peux pas.

L'endroit pour le faire est avec les attributs.

Par exemple

 [Name("FooClass")]
class Foo
{
}
 

7voto

JasonTrue Points 13615

Si vous n'avez pas l'esprit de s'en remettre à des implémentations raisonnablement mettre en œuvre la Description de la propriété, vous pouvez simplement faire

public abstract string ClassDescription {get; } 
// ClassDescription is more intention-revealing than Description

Et la mise en œuvre des classes serait faire quelque chose comme ceci:

static string classDescription="My Description for this class";
override string  ClassDescription { get { return classDescription; } }

Ensuite, vos classes sont tenus de respecter le contrat de disposer d'une description, mais vous le laissez à eux de le faire intelligemment. Il n'y a aucun moyen de préciser la mise en œuvre dans une manière orientée objet (sauf par le biais de traitements cruels, fragile hacks).

Cependant, dans mon esprit, c'est la Description des métadonnées de classe, donc je préfère utiliser l'attribut mécanisme comme d'autres l'ont décrit. Si vous êtes particulièrement préoccupé par les multiples utilisations de la réflexion, de créer un objet qui reflète plus l'attribut que vous êtes préoccupé par le, et de stocker un dictionnaire entre le Type et la Description. Qui permettra de réduire au minimum la réflexion (autre que la course de type au moment de l'inspection, ce qui n'est pas si mauvais que ça). Le dictionnaire peut être stocké en tant que membre de quelque classe que généralement besoin de cette information, ou, si les clients sur le domaine exigent, par l'intermédiaire d'un singleton ou objet de contexte.

6voto

Chad Grant Points 16571

Si elle est statique, il n'y a qu'une seule instance de la variable, je ne vois pas comment l'héritage aurait du sens si nous pouvions faire ce que vous voulez accomplir avec des variables statiques dans des classes dérivées. Personnellement, je pense que vous allez trop loin pour essayer d'éviter une var var.

Pourquoi pas juste la manière classique?

 abstract class AbstractBase
{
    protected string _Description = "I am boring abstract default value";
}

class Foo : AbstractBase {

     public Foo() {
       _Description = "I am foo!";
     }
}
 

6voto

bdonlan Points 90068

Combinant statique et abstraite est un peu vide de sens, oui. L'idée derrière statique est une nécessité de ne pas présenter une instance de la classe afin d'utiliser le membre en question; toutefois, avec le résumé, on s'attend à une instance d'une classe dérivée qui fournit une mise en œuvre concrète.

Je peux voir pourquoi vous voulez ce genre de combinaison, mais le fait est que le seul effet serait de refuser la mise en œuvre utilisation de "ceci" ou tout les membres non statiques. Qui est le parent de la classe de dicter une restriction dans la mise en œuvre de la classe dérivée, même si il n'y a aucune différence entre l'appel d'un abstract ou "statique abstrait" membre (comme aurait besoin d'un exemple concret pour comprendre la mise en œuvre qu'à l'utilisation)

3voto

Yuliy Points 8854

Il n'est pas statique s'il doit être appelé sur une instance.

Si vous ne l'appelez pas sur une instance, il n'y a pas de polymorphisme en jeu (c'est-à-dire que ChildA.Description n'a aucun lien avec ChildB.Description en ce qui concerne le langage).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X