0
votes

Pourquoi gettype () d'une classe "tranchée" par interface me dise son type de classe qui n'est pas?

Voici Mon code: XXX

I Init une classe par interface (implémenté par la classe).

évidemment, impossible d'accéder à a.myvalue , car correctement rexter.isampleinterface ne contient pas de telle Définition.

mais si je demande à compiler quel type est a , il sortira rexester.a (qui n'est pas, je crois).

pourquoi? Et plus important, quel genre de classe est a ? Une sorte de classe de tranchée hybride limitée par son interface? Je ne sais pas comment je le définirais ...


3 commentaires

L'instance est toujours la même, peu importe ce que vous le jetez.


Runtime! = Temps de compilation


Vous semblez avoir cessé de commenter des réponses - il est difficile de savoir si vous n'êtes pas sûr des choses ou si vous attendez-vous simplement de décider d'une éventuelle accepter. Si vous n'êtes toujours pas clair sur quelque chose, cela vous aiderait si nous savions quoi.


3 Réponses :


2
votes

Quelles méthodes vous pouvez appeler (réflexion extérieure / dynamique ) sont basées sur le type compilation-time de la variable .

Caste de référence (qui est ce qui a fait de la référence d'une référence existante à une interface des outils informatiques. Ne modifiez pas le type de l'objet du tout. Mais si vous stockez le résultat de cette distribution dans une variable, le type de variable est ce qui compte.

Il n'y a rien de comparable à la tranchage de C ++ (ce que je présume que vous parlez de tranchant) dans le monde .Net, que je peux penser - vous ne le feriez certainement pas de rédiger un code simple.

Une variable déclarée à un type d'interface ne contiendra jamais une référence à quelque chose qui est "juste" cette interface. Il s'agira toujours d'un objet de type structure / classe de béton spécifique.


5 commentaires

Dites-vous cela en mémoire, il allouera de l'espace pour un A ? Même si une partie ne peut-elle pas être accessible?


Vous avez appelé nouveau A () - cela va toujours produire un objet A -sized. Par la suite, il n'y a qu'un seul objet que plusieurs références peuvent faire référence. Et vous pouvez accéder aux autres membres en moulant à A .


@Markezzz Vous souvenez que ces classes et interfaces sont Types de référence par défaut dans C #, ce qui signifie que la variable A est une référence à un objet en mémoire, Pas l'objet lui-même, il peut donc faire référence à un A ou a b . Il serait analogue à isampleterface * en C ++.


Je dirais IsamletteInterface & :) Ouais, je viens surtout de C ++, je le suis à peine ... :)


Non, je veux dire littéralement isampleterface * . C'est une référence référence ("pointeur" en C ++) à un objet.



0
votes

a.myvalue code> On ne peut pas accéder car il est en portée de la portée, car isampleinterface code>

a.getype () code> correctement dans A code> car cela est résolu à l'exécution à l'instance du type attribué à A code>, qui est a code>. Il est seulement dans la portée comme isamletteinterface code>. P>

par exemple ... p> xxx pré>

Vous créez une instance / em> de a code> déclaré comme isampleinterface code>. p> xxx pré>

Vous pouvez accéder aux choses forts> > déclaré. p>

Console.WriteLine(a.GetType());


1 commentaires

Je pense qu'u portée au lieu de type ici est assez déroutant compte tenu de la signification existante de de portée en C #.



1
votes

Mais si je demande à compiler quel type est a code>, il sortit rexester.a code> (qui n'est pas, je crois) p>

Si par "Demandant au compilateur", vous voulez dire appeler a.getype () code>, ce n'est pas ce que tu fais. Vous demandez au em> pour le type réel em> de l'objet que a code> références. Le temps d'exécution vous dit correctement qu'il s'agit d'un rexester.a code>. P>

Le compilateur em> d'autre part, ne le sait pas. La variable em> est déclarée sous la forme d'un isampleinterface code>, de sorte que tout le compilateur peut effectuer en toute sécurité est de se lier aux méthodes définies par l'interface. p>

si vous casting em> la variable à un A code>, alors vous em> peut accéder à ses membres: p>

Console.WriteLine(GetCompileTimeType(a));


5 commentaires

"Le temps d'exécution vous dit correctement que c'est un réxicité.a", pas sûr de cela. Pourquoi? Au moment de l'exécution, ce n'est toujours pas un A du tout. Ne peut pas accéder aux membres de celui-ci, car ils sont sortis de la portée isampleInterface .


@markzzz - Oui c'est. Ces lancers sont ce que Eric Lippert se réfère à Conversions de préservation de la représentation < / I> . Je pense qu'en C ++, ce serait quelque chose de similaire à Reterpret_cast <> - Vous ne changez pas les bits / octets, vous n'effectuez pas une routine de conversion. C'est toujours la «même chose». Références (a) A, A) Retourne True .


La coulée ne change pas du tout l'objet sous-jacent. Les mises de valeur sur les types de valeur vous donneront un objet neuf des types de caractères demandés sur Types de référence vous donneront une référence différente au même objet. Je suis aussi venu d'un contexte C ++ afin que la compréhension des types de référence peut être délicate. Il suffit de comprendre que c # dans pas une extension de C ++, une partie de la syntaxe peut être déroutante si vous essayez de le traduire en C ++.


"Les fichiers sur les types de référence vous donneront une référence différente au même objet" - uniquement, si, à nouveau, la distribution est l'une de ces ERIC se réfère à des conversions de préservation de la représentation. Des moulages qui finissent par appeler un opérateur de conversion (normalement) ne renvoient pas le même objet.


@Damien_the_unbeliever assez juste, il y a des exceptions. Mon point principal est que le casting d'une référence ne change pas l'objet réel.