Alors, quel est exactement un bon cas d'utilisation pour l'implémentation explicite d'une interface ?
Est-ce seulement pour que les personnes utilisant la classe n'aient pas à regarder toutes ces méthodes/properties dans intellisense ?
Alors, quel est exactement un bon cas d'utilisation pour l'implémentation explicite d'une interface ?
Est-ce seulement pour que les personnes utilisant la classe n'aient pas à regarder toutes ces méthodes/properties dans intellisense ?
Si vous implémentez deux interfaces, toutes deux avec la même méthode et des implémentations différentes, alors vous devez les implémenter explicitement.
public interface IDoItFast
{
void Go();
}
public interface IDoItSlow
{
void Go();
}
public class JustDoIt : IDoItFast, IDoItSlow
{
void IDoItFast.Go()
{
}
void IDoItSlow.Go()
{
}
}
Il est utile de cacher le membre non préféré. Par exemple, si vous implémentez à la fois IComparable<T>
et IComparable
il est généralement plus agréable de cacher le IComparable
pour ne pas donner l'impression que l'on peut comparer des objets de types différents. De même, certaines interfaces ne sont pas conformes à CLS, comme IConvertible
Si vous n'implémentez pas explicitement l'interface, les utilisateurs finaux des langages qui exigent la conformité CLS ne pourront pas utiliser votre objet. (Ce qui serait très désastreux si les implémenteurs de la BCL ne cachaient pas les membres IConvertible des primitives :))
Une autre note intéressante est que, normalement, l'utilisation d'une telle construction signifie que les structures qui implémentent explicitement une interface ne peuvent être invoquées que par le biais d'une boîte au type de l'interface. Vous pouvez contourner ce problème en utilisant des contraintes génériques : :
void SomeMethod<T>(T obj) where T:IConvertible
Ne mettra pas en boîte un int lorsque vous lui en passez un.
Quelques raisons supplémentaires pour implémenter une interface de manière explicite :
compatibilité rétroactive : En cas de modification de l'interface 'ICloneable', les membres de la classe de méthodes d'implémentation ne doivent pas modifier leurs signatures de méthodes.
code plus propre Il y aura une erreur de compilation si la méthode "Clone" est supprimée de ICloneable, mais si vous implémentez la méthode implicitement, vous pouvez vous retrouver avec des méthodes publiques "orphelines" inutilisées.
forte dactylographie : Pour illustrer l'histoire de supercat avec un exemple, ce serait mon code d'exemple préféré, l'implémentation de ICloneable permet explicitement à 'Clone()' d'être fortement typé lorsque vous l'appelez directement comme un membre d'instance de MyObject :
public class MyObject : ICloneable
{
public MyObject Clone()
{
// my cloning logic;
}
object ICloneable.Clone()
{
return this.Clone();
}
}
Une autre technique utile consiste à faire en sorte que l'implémentation publique d'une fonction d'une méthode renvoie une valeur plus spécifique que celle spécifiée dans une interface. Par exemple, un objet peut implémenter iCloneable, mais sa méthode Clone, visible par le public, peut retourner son propre type. De même, un objet iAutomobileFactory peut avoir une méthode Manufacture qui renvoie une Automobile, mais un objet FordExplorerFactory, qui implémente iAutomobileFactory, peut avoir sa méthode Manufacture qui renvoie un FordExplorer (qui dérive de Automobile). Le code qui sait qu'il possède une FordExplorerFactory pourrait utiliser les propriétés spécifiques de FordExplorer sur un objet retourné par une FordExplorerFactory sans avoir à effectuer un typage, tandis que le code qui sait simplement qu'il possède un certain type de iAutomobileFactory traiterait simplement son retour comme une Automobile.
Il peut garder l'interface publique plus propre pour implémenter explicitement une interface, c'est-à-dire votre File
pourrait mettre en œuvre IDisposable
de manière explicite et fournir une méthode publique Close()
ce qui pourrait avoir plus de sens pour un consommateur que Dispose(
).
F# uniquement offre une mise en œuvre explicite de l'interface, de sorte que vous devez toujours effectuer un cast vers l'interface particulière pour accéder à sa fonctionnalité, ce qui permet une utilisation très explicite (sans jeu de mots) de l'interface.
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.