Déclarer une fonction membre dans l'interface
Tout d'abord, je suis assez novice en C#. Je voudrais avoir une interface déclarer une fonction membre comme dans le morceau de code suivant
interface IMyInterface {
void MyAction() {
//do stuff depending on the output of function()
}
void Function();
}
ici Function
est virtuelle pure et devraient être mises en œuvre par les enfants de IMyInterface
. Je pourrais utiliser une classe abstraite au lieu d'une interface, mais je ne pouvais pas hériter d'autres classes... Disons, par exemple, que MyAction
est recursiverly à la recherche d'un répertoire pour les fichiers et l'application de Function
à aucun fichier trouvé pour faire mon exemple clair.
Comment changer ma conception afin de surmonter la contrainte que les interfaces ne peuvent pas mettre en œuvre des classes ?
Edit : En C++, ce que je voudrais faire est de l'utilisation des modèles en tant que tel
template<class A>
static void MyAction(const A& a) {
//do stuff depending on the output of A::Function()
};
class MyClass {
void Function();
};
Je me demandais si il y avait un moyen élégant pour ce faire, l'utilisation d'interfaces en C#.
Les Interfaces ne peut pas contenir de code. Ils suffit de définir les membres qu'une mise en œuvre de la classe doit fournir.
Pourriez-vous préciser exactement ce que vous cherchez à faire?
J'ai édité ma question. Désolé de ne pas être clair dans la première place.
Ne pas oublier que "la sortie de la fonction()" est
void
, ce qui est assez difficile à "faire des trucs en fonction".OriginalL'auteur vanna | 2013-01-24
Vous devez vous connecter pour publier un commentaire.
En C# vous n'avez pas l'héritage multiple. Vous pouvez contourner cette limitation en utilisant composition.
Définir votre interface comme ceci (
Function
ne doit pas être défini ici):Déclarer une classe abstraite avec un résumé
Function
et la mise en œuvre de cette interface:De cette classe abstraite on peut en tirer une mise en œuvre concrète. Ce n'est pas votre "finale" de la classe, mais il sera utilisé pour le composer.
Maintenant, venons-en à votre "finale", composé de la classe. Il va dériver à partir de
SomeBaseClass
et de mettre en œuvreIMyInterface
par l'intégration de la fonctionnalité deConcreteMyInterface
:Mise à JOUR
En C#, vous pouvez déclarer des classes locales. Cela vient encore plus proche de l'héritage multiple, que vous pouvez obtenir tout dans la composition de la classe.
OriginalL'auteur Olivier Jacot-Descombes
La seule façon de traiter directement ce serait d'utiliser une classe abstraite, que l'interface ne peut pas contenir de "logique" de n'importe quelle forme, et est simplement un contrat.
Une alternative, cependant, serait de faire une interface et une classe statique. Vous pouvez ensuite placer votre logique dans une extension de la méthode à l'aide de l'interface.
Les principaux inconvénients ici sont de plusieurs types, ce qui réduit la maintenance, et un manque de visibilité.
Et pourtant, j'ai peur qu'une nouvelle marque de C# l'utilisateur peut ne pas comprendre la distinction entre une méthode d'extension et une véritable méthode d'instance. Il peut causer des problèmes si vous ne comprenez pas comment ils sont différents.
Je suis d'accord - je ne pense pas que les méthodes d'extension doit être un premier choix de l'approche de conception. Meilleur de gauche pour les cas où vous avez besoin d'étendre le comportement sur les classes que vous ne pouvez pas modifier directement.
Je suis entièrement d'accord, c'est pourquoi je spécifiquement mentionné qu'il ya des inconvénients à cette approche. Compte tenu de l'OP (à l'aide d'une interface, mais la prestation de la logique), cela peut être une approche raisonnable, cependant.
J'aime cette approche. Si j'ai une interface garanti de certains membres, il est logique d'exposer commun des comportements compte tenu de ces membres, en particulier si elles sont toutes publiques. Je pensais que le point de l'ensemble des interfaces a été de se débarrasser de l'héritage multiple...
OriginalL'auteur Reed Copsey
Vous pouvez définir
MyAction
comme méthode d'extension:Exemple:
De sortie:
En fait, presque tout ce qui a trait à LINQ est conçu de cette façon. Il y a un minimum d'interface implémentée par les classes (IEnumerable<T>) et une classe statique avec plusieurs dizaines de méthodes d'extension (Énumérable). Bien entendu, cette conception a des limites qui doivent être compris avant d'être appliquée, et je suis d'accord que ce n'est probablement pas le meilleur choix pour un débutant.
cet exemple prend en charge mon point de LINQ est conçu pour fournir comportement sur les classes qui les développeurs (dans ce cas, Microsoft) n'ont aucun contrôle sur (dans ce cas, à tout jamais écrite par quelqu'un qui implémente l'interface IEnumerable).
OriginalL'auteur dtb
Interfaces ne peuvent pas mettre en œuvre tout comportement, ils sont juste des contrats. Si vous souhaitez mettre en place une certaine logique, tandis que la définition d'un contrat, vous pourriez utiliser une classe abstraite.
En fait, vous n'avez jamais posé une question. Vous avez seulement fait un certain nombre de déclarations. La question implicite qui se pose est: "comment puis-je définir la mise en œuvre d'une méthode dans une interface?" et le (bon) la réponse est, vous ne pouvez pas. Si vous avez un problème que vous souhaitez résoudre, et que vous voulez savoir comment le résoudre, puis de décrire le problème, ne pas se demander comment définir une méthode dans une interface.
OriginalL'auteur Claudio Redi
À cette fin . vous avez besoin de définir une classe abstraite.
Vous pouvez fournir des implémentations par défaut ou vous pouvez laisser la mise en œuvre de la classe dérivée.
Si la classe dérivée de vouloir remplacer quelque chose qu'ils peuvent toujours le faire .
Cela leur donne la flexibilité pour l'utilisation de base ainsi que les changements qu'ils veulent remplacer.
OriginalL'auteur Tabish
Déclarer la fonction de l'interface (Signature et types de retour), dans une interface,
Ensuite créer une classe abstraite qui est défini pour mettre en œuvre cette interface, et de mettre en œuvre une base par défaut de mise en œuvre dans la classe abstraite. Ensuite, créer d'autres classes concrètes qui héritent de la classe abstraite, mais si nécessaire, remplacer les classes abstraites de la base de la mise en œuvre avec des différents la mise en œuvre.
OriginalL'auteur Charles Bretana
Ce genre de problème peut-être préférable de surmonter la séparation de la externe comportements;
MyAction
dans ce cas, à partir de la mise en œuvre interne;MyFunction
.Le point ici est de comprendre ce que devrait être une partie de l'interface/le contrat entre cette classe et les autres, et ce qui devrait être le cadre de la mise en œuvre de ce contrat.
Ici, le contrat entre cet objet et de ses consommateurs est défini;
Maintenant, une classe qui implémente cette interface, et met également en œuvre un comportement particulier;
Et enfin, une mise en œuvre concrète qui concerne les résultats de la fonction MyFunction d'une manière bien particulière;
OriginalL'auteur RJ Lohan
Une interface est un contrat, et ne peut pas contenir de mise en œuvre.
À partir de votre déclaration ci-dessus:
Je crois que vous frappez la "pourquoi est-ce que C# supporte pas l'héritage multiple" question.
Voici un Article sur CodeProject Simulé l'Héritage Multiple en C#. Vous devriez être en mesure de suivre ce modèle pour parvenir à une solution à l'héritage simple modèle de C#.
Bon point, merci. J'ai édité ma réponse en fonction de votre commentaire.
OriginalL'auteur Philip Tenn
C'est un projet de fonctionnalité pour C# 8.0:
https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md
OriginalL'auteur Duanne