2009-02-04 5 views
47

Disons que j'ai une interface IFoo et que toutes les sous-classes de IFoo doivent remplacer la méthode ToString de Object. Est-ce possible?Forcer les sous-classes d'une interface à implémenter ToString

ajoutant simplement la signature de la méthode à IFoo en tant que telle ne fonctionne pas:

interface IFoo 
{ 
    String ToString(); 
} 

puisque toutes les sous-classes étendent Object et fournissent une mise en œuvre de cette façon, le compilateur ne se plaint pas. Aucune suggestion?

+0

http: // stackoverflow.com/questions/239408/can-i-force-subclasses-to-override-a-method-without-making-it-abstract <-? même? ou juste très similaire? –

Répondre

68

Je ne crois pas que vous pouvez le faire avec une interface. Vous pouvez utiliser une classe de base abstraite si:

public abstract class Base 
{ 
    public abstract override string ToString(); 
} 
+0

J'espérais rester avec les interfaces puisque je les ai déjà écrites, devinez que je vais devoir mordre la balle et changer de classe abstraite. Merci. – rjohnston

+0

Grande réponse (et je pense que la seule possibilité raisonnable), mais il a un inconvénient dans le manque de support de C# pour l'héritage multiple. Toute classe qui doit hériter de Base ne peut hériter d'aucune classe autre que Base, par exemple MyClass: ThirdPartyClass, Base // mot possible – AlanK

21
abstract class Foo 
{ 
    public override abstract string ToString(); 
} 

class Bar : Foo 
{ 
    // need to override ToString() 
} 
+1

La question était "Puis-je faire cela avec une interface?", Et non "Comment faire?" , Mais merci quand même. – rjohnston

0

Je ne pense pas que vous pouvez forcer une sous-classe à dérogation l'une des méthodes virtuelles de la classe de base à moins que ces méthodes sont abstraites.

1

L'implémentation d'une méthode d'interface scelle implicitement la méthode (ainsi que son remplacement). Donc, à moins que vous ne le disiez autrement, la première implémentation d'une interface termine la chaîne de substitution en C#.

Essential .NET

Résumé class = votre ami

Vérifier this question

6

Jon & Andrew: Ce truc abstrait est vraiment utile; Je n'avais aucune idée que vous pouviez terminer la chaîne en la déclarant comme abstraite. Cheers :)

Dans le passé, quand j'ai exigé que ToString() être outrepassée dans les classes dérivées, je l'ai toujours utilisé un modèle comme les suivantes:

public abstract class BaseClass 
{ 
    public abstract string ToStringImpl(); 

    public override string ToString() 
    { 
     return ToStringImpl(); 
    }  
} 
1

Je sais que cela ne répond pas votre question, mais puisqu'il n'y a aucun moyen de faire ce que vous demandez, j'ai pensé que je partagerais ma propre approche pour que les autres voient. J'utilise un hybride de Mark et Andrew solutions proposées.

Dans mon application, tous les domaines-entités dérivent d'une classe de base abstraite:

public abstract class Entity 
{ 
    /// <summary> 
    /// Returns a <see cref="System.String"/> that represents this instance. 
    /// </summary> 
    public override string ToString() 
    { 
     return this is IHasDescription 
        ? ((IHasDescription) this).EntityDescription 
        : base.ToString(); 
    } 
} 

L'interface se définit uniquement un accesseur simple:

public interface IHasDescription : IEntity 
{ 
    /// <summary> 
    /// Creates a description (in english) of the Entity. 
    /// </summary> 
    string EntityDescription { get; } 
} 

Alors maintenant, il y a une chute arrière mécanisme intégré - ou en d'autres termes, un Entity qui implémente IHasDescription doit fournir le EntityDescription, mais tout Entity peut encore convertir en une chaîne. Je sais que ce n'est pas radicalement différent des autres solutions proposées ici, mais j'aime l'idée de minimiser la responsabilité du type de base Entity, de sorte que la mise en œuvre de l'interface de description reste facultative, mais vous êtes obligé de implémente réellement la méthode de description si vous implémentez l'interface.

à mon humble avis, les interfaces qui sont mises en œuvre par la mise en œuvre comme la classe de base object ne devrait pas « compter » - il serait agréable d'avoir une option de compilateur pour cela, mais, oh bien ...

+0

Vous pouvez utiliser 'as' au lieu de' is' pour éviter une seconde distribution. – chwarr

Questions connexes