est-il possible de définir une interface avec des méthodes de mise en œuvre optionnelles? Par exemple, j'ai la définition d'interface suivante comme idatatreader dans ma bibliothèque principale: Cependant, dans mes implémentations actuelles, la méthode STOP () n'a jamais été utilisée ou mise en œuvre. Dans toutes mes classes de mise en œuvre, cette méthode doit être mise en œuvre avec ThrowNplementaedexCetion () par défaut: P> reader.StartRead(myData);
....
// some where when I need to stop reader
IStop stoppable = reader as IStop;
if (stoppable != null ) stoppable.Stop();
...
6 Réponses :
Si aucune classe dans votre code n'applique réellement stop () code>, et vous n'avez pas plans défini em> pour le faire à l'avenir, alors vous n'avez pas besoin de il dans votre interface. Sinon, si certains em> mais pas tous em> de vos objets sont "stoppables", l'approche correcte est en effet pour en faire une interface distincte telle que
istoppable code >, et les clients devraient alors interroger pour cela au besoin. P>
Si votre implémentation ne met pas en œuvre la méthode d'interface, la méthode de l'interface, il enfreint l'évidence le contrat fourni avec votre interface. Soit vous implémentez la méthode d'arrêt de manière appropriée (pas en jetant une exception et non en le laissant à vide) ou vous devez redéfinir votre interface (afin de modifier le contrat). P>
meilleures salutations p>
intéressant. Je vais devoir vous citer ici: P>
Cependant, dans mon courant les implémentations, la méthode Stop () a jamais été utilisé ou mis en œuvre. Dans tout Mes cours de mise en œuvre, cette méthode doit être mis en œuvre avec lancer Notimplementedexcétion () par défaut: p> blockQuote>
Si tel est le cas, vous avez deux options: p>
- Retirez la méthode Stop () de l'interface. S'il n'est pas utilisé par tous les em> implément de l'interface, il n'appartient clairement pas là em>.
- Au lieu d'une interface, convertissez votre interface en une classe de base abstraite. De cette façon, il n'est pas nécessaire de remplacer une méthode d'arrêt vide () jusqu'à ce que vous ayez besoin de. LI> ul> li> ol>
mise à jour strong> Le seul moyen de penser que les méthodes peuvent être facultatives permettent d'attribuer une méthode à une variable (d'un type de délégué similaire à la signature de la méthode), puis à évaluer si la méthode est null avant de tenter l'appeler n'importe où. p> Ceci est généralement effectué pour les gestionnaires d'événements, dans lequel le gestionnaire peut ou non être présent et peut être considéré comme facultatif. P>
Je vois ce que tu veux dire. J'ai effectivement supprimé la méthode. Ceci est dans mon contrôle. Cependant, après que j'ai fait cela, j'ai essayé de savoir s'il y a un moyen de faire des options de méthode dans .net? J'aime beaucoup le garder là-bas comme facultatif au cas où je devais arrêter le processus par interface.
Si la méthode est inappropriée pour votre implémentation, lancez Cependant, il est préférable de mettre uniquement des choses dans une interface lorsque vous en avez besoin, si vous êtes toujours dans une position où vous pouvez supprimer Il n'y a pas de support unifié pour les membres d'interface optionnels dans la langue ou le CLR. P> InvalidOrationException Code>
Tout comme la plupart des itérateurs font lorsque vous appelez réinitialiser code> sur eux. Une alternative est
notsupportedexception code>
qui tend ce qui tend Pour être utilisé par system.io code>. Ce dernier est plus logique (car il n'a rien à voir avec l'état actuel de l'objet, juste son type de béton), mais le premier est plus couramment utilisé dans mon expérience. P>
arrêter code>, je le ferais si j'étais vous. p>
Il y a le système.NotsupportedException à .NET;)
se mettre d'accord. On dirait que la mise en œuvre facultative n'est pas prise en charge en C #. J'ai de nombreux cas pour implémenter des interfaces de base .NET avec des méthodes non utilisées.
@Oliver: C'est vrai. C'est un peu un gâchis ayant les deux - je modifierai ma réponse.
c # version 4 ( ou vnext ) envisage d'envisager Mise en œuvre des interfaces - J'ai entendu dire que sur Interfaces avec la mise en œuvre par défaut se comporterait quelque peu comme des classes de base abstraites. Maintenant que vous pouvez hériter de plusieurs interfaces, cela pourrait signifier que c # peut obtenir de multiples héritage sous forme d'interfaces avec des implémentations par défaut. P> jusqu'à ce que vous puissiez vous échapper avec des méthodes d'extension ... P> Ou votre type pourrait utiliser les délégués. P> interface IOptionalStop
{
Action Stop { get; }
}
public class WithStop : IOptionalStop
{
#region IOptionalStop Members
public Action Stop
{
get;
private set;
}
#endregion
public WithStop()
{
this.Stop =
delegate
{
// we are going to stop, honest!
};
}
}
public class WithoutStop : IOptionalStop
{
#region IOptionalStop Members
public Action Stop
{
get;
private set;
}
#endregion
}
public class Program
{
public static string Text { get; set; }
public static void Main(string[] args)
{
var a = new WithStop();
a.Stop();
var o = new WithoutStop();
// Stop is null and we cannot actually call it
a.Stop();
}
}
Il n'y a pas de "implémentation par défaut pour les interfaces" en C # 4.0.
Trop triste. Je pense que cela devrait être très facile de le faire. Il suffit d'ajouter une nouvelle directive clé Travail facultatif avant une méthode pour que .NET Compiler génère des codes corporels vides pour cette méthode. Appelez cette méthode facultative si elle n'est pas implémentée ne fera rien et aucune exception. Bien sûr, cela peut ouvrir une porte pour que les gens puissent lancer trop de mauvaises interfaces. Il y a une valeur pour avoir une implémentation facultative, mais elle peut être abusée. Juste mon commentaire.
Je vois des fautes de frappe. Désolé. Il est trop tard au Canada maintenant.
Qu'en est-il de l'approche déléguée dans l'exemple que j'avais donné qui fonctionnerait avec la version actuelle de C #?
Je l'aime bien. J'ai pensé à déléguer mais pas aussi propre que le vôtre. Cependant, j'ai toujours un chèque si le délégué est nul ou non et définir un autre délégué à mettre en œuvre.
Vous pouvez créer une méthode d'extoSion .invokesafe () pour cela pour ignorer si le délégué cible est null ...
Pour info, une autre approche assez courante dans le BCL est Supports * code> sur la même interface, c'est-à-dire
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) {
foreach(T item in items) list.Add(item);
}