Qu’est-ce que l’interface Duck Typing?

J’ai entendu le mot Interface Duck Typing, mais je ne comprends pas du tout ce que c’est. Alors j’ai lu un wiki à ce sujet et ils ont dit:

Dans la programmation informatique avec des langages de programmation orientés object, la saisie simplifiée est un style de saisie dans lequel les propriétés et méthodes d’un object déterminent la sémantique valide, plutôt que son inheritance d’une classe particulière ou l’implémentation d’une interface explicite. Le nom du concept fait référence au test de canard.

Mais je ne pouvais toujours pas comprendre ce que c’était. J’ai donc vu leur programme mais ils utilisent dynamic mot clé dynamic pour appeler la fonction quack() & feather() de toutes les classes.

Je vous demanderais à tous s’il vous plaît d’expliquer de manière simple ce qu’est Interface Duck Typing et comment l’implémenter en C # v2.0 car il n’y a pas de mot clé dynamic .

 using System; namespace DuckTyping { public class Duck { public void Quack() { Console.WriteLine("Quaaaaaack!"); } public void Feathers() { Console.WriteLine("The duck has white and gray feathers."); } } public class Person { public void Quack() { Console.WriteLine("The person imitates a duck."); } public void Feathers() { Console.WriteLine("The person takes a feather from the ground and shows it."); } } internal class Program { private static void InTheForest(dynamic duck) { duck.Quack(); duck.Feathers(); } private static void Game() { Duck donald = new Duck(); Person john = new Person(); InTheForest(donald); InTheForest(john); } private static void Main() { Game(); } } } 

Le typage de canard permet à un object d’être transmis à une méthode qui attend un certain type même s’il n’hérite pas de ce type. Tout ce qu’il a à faire est de prendre en charge les méthodes et propriétés du type attendu utilisé par la méthode. Je souligne cette dernière phrase pour une raison. Supposons que nous ayons une méthode qui prend une instance de canard et une autre qui prend une instance de lapin. Dans un langage à typage dynamic qui prend en charge le typage de canard, je peux transmettre mon object à la première méthode à condition que mon object prenne en charge les méthodes et propriétés de canard utilisées par cette méthode. De même, je peux passer mon object dans la deuxième méthode, à condition qu’il prenne en charge les méthodes et les propriétés du lapin appelées par la deuxième méthode. Est-ce que mon object est un canard ou est-ce un lapin? Comme l’image ci-dessus, ce n’est ni l’un ni l’autre. Dans de nombreux langages dynamics (sinon la plupart), il n’est pas nécessaire que mon object prenne en charge toutes les méthodes et propriétés de canard pour être transmis à une méthode qui attend un canard. Il en va de même pour une méthode qui attend un lapin. Il suffit de prendre en charge les méthodes et les propriétés du type attendu qui sont réellement appelées par la méthode.

S’il vous plaît se référer à cela pour avoir une idée sur Duck Typing

http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/

C # a un système de types nominal, la compatibilité des types est donc basée sur leurs noms. Dans votre exemple, vous avez deux classes avec une méthode Quack . Cependant, il n’existe aucun moyen d’écrire une méthode pouvant prendre des occurrences de ces deux classes et invoquer leur méthode Quack .

En C # 2, la solution serait d’introduire une interface et de la mettre en œuvre par les deux classes:

 public interface IQuack { void Quack(); } public class Duck : IQuack { } public class Human : IQuack { } 

Maintenant, vous pouvez créer une méthode prenant une instance IQuack et pouvant appeler Human.Quack et Duck.Quack . En C #, les méthodes sont résolues ‘tôt’ au moment de la compilation. Vous devez donc créer un type nommé qui prenne en charge les opérations nécessaires à la méthode pour que la compilation réussisse. Notez qu’il rest un élément d’exécution à appeler ces méthodes, car l’implémentation réelle d’ IQuack.Quack doit être résolue au moment de l’exécution en fonction du type réel de l’argument.

Dans un système de typage de canard, aucune tentative n’est faite pour valider qu’une méthode existe avant l’exécution. Tout ce qui est requirejs est qu’un object donné prenne en charge l’opération en ce sens qu’il a le bon nom et qu’il prend le nombre de parameters requirejs (aucun dans ce cas), d’où l’expression “si il plaisante comme un canard”.

La saisie de texte en C # 2 ne peut être effectuée qu’en utilisant la reflection. Dans ce cas, vous accepteriez un argument d’ object et rechercheriez vous-même les méthodes requirejses:

 public static void MakeQuack(object duck) { MethodInfo quackMethod = duck.GetType().GetMethod("Quack", Type.EmptyTypes, null); if (quackMethod!=null) { quackMethod.Invoke(duck, new object[] { }); } else { throw new ArgumentException("No Quack() method found on target"); } } 

C # 4 rend cela beaucoup plus simple avec dynamic :

 public static void MakeQuack(dynamic duck) { duck.Quack(); } 

Cela indiquerait que c’est une façon de coder où vous dites au compilateur:

“Hé, crois-moi, je connais les méthodes et propriétés sockets en charge par cet object. Tu n’as pas besoin de les vérifier pour moi pendant que je code.”

Une fois que vous avez exécuté votre application, le compilateur dit: “Ok, voyons si je peux te faire confiance. Laisse-moi faire une liaison d’exécution.”

Si vous avez ensuite commis une erreur, par exemple en utilisant une méthode non prise en charge, le compilateur va crier: “Hé mec, ceci n’est pas pris en charge! Vérifiez mon exception RuntimeBinderException!”

À propos de la frappe de canard:

Nous n’avons pas besoin de savoir ce qu’est l’object, mais nous voulons simplement laisser l’object faire quelque chose s’il le peut.

Exemple:

Exemple, si voici les choses que nous voulons que les objects suivants fassent.

 PleaseWalk(new Dog()); PleaseRun(new Duck()); PleaseWalk(new Cup()); PleaseFly(new Man()); PleaseFly(new Bird()); 

Et, voici le résultat après que nous demandions aux objects ci-dessus de faire les choses. entrez la description de l'image ici

Donc, nous n’avons pas besoin de vérifier ce qu’est l’object, mais nous pouvons le laisser faire quelque chose d’assez. Voici le code que j’ai écrit en C #.

 private void PleaseWalk(object obj) { ssortingng Method = "Walk"; MethodInfo walkMethod = obj.GetType().GetMethod(Method, Type.EmptyTypes, null); if (walkMethod != null) { walkMethod.Invoke(obj, new object[] { }); } else { Console.WriteLine(ssortingng.Format("I can not {0} because {1}", Method, WhoAreYou(obj))); } } private ssortingng WhoAreYou(object unknown) { MethodInfo whoAreYou = unknown.GetType().GetMethod("WhoAreYou", Type.EmptyTypes, null); return whoAreYou.Invoke(unknown, new object[] { }).ToSsortingng(); }