Question

Je ne parle pas de transtypage dynamique dans le sens de transtyper une classe inférieure d'interface ou de base vers une classe plus dérivée, je veux dire de prendre une définition d'interface que j'ai créée, puis de transtyper dynamiquement vers cette interface un objet différent, PAS dérivé de cette interface mais supportant tous les appels.

Par exemple,

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = (dynamic<IMyInterface>)myTextBox;

Cela pourrait être réalisé lors de la compilation pour les types connus et de l'exécution pour les instances déclarées avec dynamique. La définition de l'interface est connue, de même que le type (dans cet exemple), afin que le compilateur puisse déterminer si l'objet prend en charge les appels définis par l'interface et effectuer des opérations magiques pour que le transtypage s'effectue.

Je suppose que cela n'est pas pris en charge dans C # 4 (je n'ai pas pu trouver de référence), mais j'aimerais le savoir avec certitude. Et si ce n’est pas le cas, j’aimerais discuter de la question de savoir si cela devrait être inclus dans une variante future du langage ou non, ainsi que les raisons pour et contre. Pour moi, cela semble être un ajout intéressant pour permettre un polymorphisme plus important dans le code sans avoir à créer de nouveaux types entiers pour envelopper les types de framework existants.

Mettre à jour
Au cas où quelqu'un m'accuserait de plagiat, je n'étais pas au courant de Jon Skeet ayant déjà proposé cela . Cependant, il est bon de savoir que nous avons pensé à une syntaxe extrêmement similaire, ce qui suggère qu’elle pourrait au moins être intuitive. En attendant, "ayez une idée originale" reste sur ma liste de seau pour un autre jour.

Était-ce utile?

La solution

Je pense que Jon Skeet a eu une telle proposition ( http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx ), mais je n’ai pas encore entendu dire que le C # 4.0 allait l’avoir.

Autres conseils

Je pense que c'est problématique. Vous introduisez un couplage entre deux classes qui ne sont pas couplées.

Considérez le code suivant.

public interface IFoo
{
   int MethodA();
   int MethodB();
}

public class Bar
{
   int MethodA();
   int MethodB();
}

public class SomeClass
{
   int MethodFoo(IFoo someFoo);
}

cela devrait-il alors être légal?

int blah = someClass.MethodFoo((dynamic<IFoo>)bar);

Il semble que cela devrait être légal, car le compilateur devrait pouvoir taper dynamiquement bar comme quelque chose qui implémente IFoo.

Cependant, à ce stade, vous couplez IFoo et Bar par un appel dans une partie complètement séparée de votre code.

Si vous éditez Bar parce qu'il n'a plus besoin de MethodB, soudainement someClass.MethodFood ne fonctionne plus, même si Bar et IFoo ne sont pas liés.

De la même manière, si vous ajoutez MethodC () à IFoo, votre code se briserait à nouveau, même si IFoo et Bar ne sont apparemment pas liés.

Le fait est que, bien que cela soit utile dans certains cas où il existe des similitudes entre des objets que vous ne contrôlez pas, il existe une raison pour laquelle les interfaces doivent être explicitement attachées aux objets, et la raison en est que le compilateur peut garantir que l'objet l'implémente.

Il n’est pas nécessaire que C # prenne cela en charge, car il peut être implémenté très proprement en tant que bibliothèque.

J'ai vu trois ou quatre implémentations distinctes (j'ai commencé à en écrire une moi-même avant de les trouver). Voici le traitement le plus complet que j'ai jamais vu:

http://bartdesmet.net/blogs/bart/archive/2008/11/10/introducing-the-c-ducktaper-bridging-the-dynamic-world-with-the -static-world.aspx

Il sera probablement encore plus facile à implémenter une fois le DLR intégré dans le moteur d'exécution.

Etant donné que la classe wrapper / forwarder d’une interface donnée peut être générée une fois, puis mise en cache, puis qu’un objet donné de type inconnu peut être encapsulé une fois, il existe de nombreuses possibilités pour la mise en cache des sites d’appel, etc. les performances devraient être excellentes.

En revanche, je pense que le mot clé dynamic , qui est une fonctionnalité de langue et extrêmement complexe, est une digression inutile et potentiellement désastreuse, insérée dans une langue qui avait auparavant philosophie de typage statique claire, ce qui lui a donné une direction évidente pour une amélioration future. Ils auraient dû s'en tenir à cela et faire en sorte que l'inférence de type fonctionne de mieux en mieux jusqu'à ce que la frappe devienne plus invisible. Il y a tellement de domaines dans lesquels ils pourraient faire évoluer le langage sans casser les programmes existants, mais ils ne le font pas, tout simplement en raison de contraintes de ressources (par exemple, la raison pour laquelle var ne peut pas être utilisée ailleurs) est parce qu’ils devront réécrire le compilateur et qu’ils n’ont pas le temps).

Ils font toujours du bon travail en C # 4.0 (les fonctions de variance), mais il reste encore beaucoup à faire pour rendre le système de types plus intelligent, plus automatique et plus puissant pour détecter les problèmes au moment de la compilation. Au lieu de cela, nous obtenons essentiellement un gadget.

La structure opensource d'Impromptu-Interface le fait à l'aide du C # 4 et du dlr. .

using ImpromptuInterface;

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = myTextBox.ActLike<IMyInterface>();

Puisqu'il utilise le dlr, il fonctionnera également avec ExpandoObject et DynamicObject.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top