Supposons que j'ai une interface IFoo
et que je veux que toutes les sous-classes de IFoo
remplacent la méthode ToString
de Object. Est-ce possible?
Ajouter simplement la signature de la méthode à IFoo en tant que tel ne fonctionne pas:
interface IFoo
{
String ToString();
}
puisque toutes les sous-classes étendent Object
et fournissent une implémentation de cette façon, le compilateur ne s'en plaint pas. Aucune suggestion?
Je ne crois pas que vous puissiez le faire avec une interface. Vous pouvez utiliser une classe de base abstraite si:
public abstract class Base
{
public abstract override string ToString();
}
abstract class Foo
{
public override abstract string ToString();
}
class Bar : Foo
{
// need to override ToString()
}
Jon & Andrew: Ce tour abstrait est vraiment utile. Je ne savais pas que vous pouviez mettre fin à la chaîne en la déclarant abstraite. À votre santé :)
Dans le passé, lorsque j'avais demandé que ToString () soit écrasé dans des classes dérivées, j'avais toujours utilisé un modèle tel que celui-ci:
public abstract class BaseClass
{
public abstract string ToStringImpl();
public override string ToString()
{
return ToStringImpl();
}
}
Je sais que cela ne répond pas à votre question, mais comme il n’existe aucun moyen de faire ce que vous demandez, je pensais partager ma propre approche à la vue des autres.
J'utilise un hybride des solutions proposées par Mark et Andrew.
Dans mon application, toutes les entités de domaine proviennent 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 elle-même ne définit qu’un simple accesseur:
public interface IHasDescription : IEntity
{
/// <summary>
/// Creates a description (in english) of the Entity.
/// </summary>
string EntityDescription { get; }
}
Alors maintenant, il existe un mécanisme de secours intégré - ou, en d'autres termes, une Entity
qui implémente IHasDescription
doit fournir la EntityDescription
, mais toute Entity
peut toujours être convertie en chaîne.
Je sais que ce n'est pas radicalement différent des autres solutions proposées ici, mais j'aime bien l'idée de minimiser la responsabilité du type de base Entity
, de sorte que l'implémentation de l'interface de description reste facultative, mais vous êtes obligé d'implémenter la description. -méthode si vous implémentez l'interface.
IMHO, les interfaces implémentées par la classe de base object
ne devraient pas "compter" comme implémentées - il serait bien d'avoir une option de compilation pour cela, mais bon ...
L'implémentation d'une méthode d'interface scelle implicitement la méthode (et la redéfinit également). Donc, sauf indication contraire de votre part, la première implémentation d'une interface met fin à la chaîne de substitution en C #.
Classe abstraite = ton ami
Vérifiez cette question
Désolé d'enterrer ce vieux fil de la tombe, spécialement parce que notre cher @ jon-skeet a déjà fourni sa propre réponse .
Mais si vous souhaitez conserver l'interface et ne pas utiliser de classe abstraite, je suppose que cela est toujours possible en ayant simplement votre interface implémentant l'interface System.IFormattable .
interface IFoo : IFormattable
{
}
La seule chose à garder à l'esprit est que, pour implémenter correctement cet IFormattable, l'implémentation concrète doit également écraser la Object.ToString()
.
Ceci est clairement expliqué dans ce billet de Nice.
Votre classe de béton est maintenant comme
public class Bar : IFoo
{
public string ToString(string format, IFormatProvider formatProvider)
{
return $"{nameof(Bar)}";
}
public override string ToString()
{
return ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}
}
J'espère que cela pourra toujours aider quelqu'un.
Je ne pense pas que vous puissiez forcer une sous-classe à remplacer aucune des méthodes virtuelles de la classe de base à moins que ces méthodes ne soient abstraites.