9
votes

Pourquoi == remplacé dans System.Double mais pas dans System.int32 et quelles sont les ramifications de cela?

in c # pourquoi double remplace == mais int32 ne le fait pas et quel est l'effet?

Je regarde le MSDN Bibliothèque.

Je vois ce lien sur le double qui ne dit pas beaucoup ICI (bien que je comprenne le double est un sténographie pour l'objet double ). Il ne montre pas les méthodes par exemple ..

mais ce lien sur system.double mentionne ce que je recherche ici

Il montre l'opérateur d'égalité qui prend des doubles, ainsi surchargé.

image pour double Dans MSDN, ensuite après des méthodes (avant les champs d'inscription), il affiche les opérateurs et indique que l'exploitant d'égalité est remplacé par une application d'égalité

 Entrez la description de l'image ici

et je peux cliquer sur l'égalité sous" opérateurs "et il dit xxx

alors que je regarde quand je regarde system.int32 Image pour int32 dans msdn est inférieur à

Entrez la description de l'image ici

voir dans cette image (la page pour system.int32 ) il ressemble à == n'est pas remplacé.

Pourquoi et quelles sont les ramifications de cela?


8 commentaires

On dirait presque que la documentation est incomplète ou il y a des choses dans les coulisses, car de la page DOC indique: "Le type INT32 prend en charge les opérations mathématiques standard telles que l'addition, la soustraction, la division, la multiplication, la négation et la négation unitaire. Comme Les autres types d'intégrale, le type INT32 prend également en charge les opérateurs Bitwise et, ou, XOR, décalage gauche et de droite. Vous pouvez utiliser les opérateurs numériques standard pour comparer deux valeurs INT32, ou vous pouvez appeler la méthode comparète ou égale. "


@TYCOBB L'affichage de gars à l'aide d'ILSPY a montré cette méthode existante, afin que cela suggère qu'il n'est pas généré le code. Il le suggère également de décompiler. Et aussi, je ne doute pas que cela appelle la méthode des égaux, mais pouvez-vous citer ce qui montre que?


@TyCobB en regardant ce que Publiez Matt. Les premier et troisième écrivains () donnent un résultat différent. Donc == et les .quals ne se comportent pas de la même manière. Donc, == n'appelle pas .quals (..) , d'accord?


@barlop Yep aucun doute. Et Tycobb a montré qu'avec In32 également, == n'appelle pas .equenilles. Aucune raison de penser que cela se produit pour aucun d'entre eux.


Vous ne pouvez pas réellement appeler l'opérateur, le compilateur C # a une connaissance intégrée des types de valeur et émet toujours des opcodes.ceq. Ils agissent simplement comme des détenteurs d'emplois de documentation, utiles pour documenter le comportement de cinglé de la norme IEEE-754.


@Hanspassant de sorte que les méthodes surchargées == avec un corps sont des façons d'une certaine sorte, qui existent comme un rappel - les gens les regardent et pensent "quel est le point de cette méthode, c'est bizarre", puis qui documente le fait que IEEE 754 a Règles étranges pour == Lorsque impliquant Nan qui affecte des nombres non entiers ?! ;-) Je ne vois pas vraiment ces méthodes le documenter. Bien que je vois qu'ils ne sont là que là-bas dans des types de nombres où Nan s'applique


La meilleure façon de voir ceci est de regarder la poste d'Artfunkle. Notez la mise en œuvre de l'opérateur == () en appelant Operateur == (). Cela ferait bien sûr la bombarder votre programme avec le nom de ce site si le compilateur C # utilise en fait l'opérateur :)


@Hanspassant Oui, j'ai remarqué que, et même s'il pouvait exécuter et cela a appelé d'autres == alors il ne dit pas grand chose. Je ne sais toujours pas comment cela aide à la documentation, alors est-ce une fraude là-bas de créer un talon de documentation dans HTML qu'ils pouvaient rendre plus descriptifs et ajouter à propos de IEEE 754, puis ils ont disparu de l'énergie? Je ne vois pas comment ils ont fait la méthode de la fraude juste pour la documentation, mais je ne l'ai pas documenté dans la bibliothèque de code ou de MSDN. (uniquement dans la spécification C # qui n'a pas besoin d'un talon de code frauduleux)


3 Réponses :


-1
votes

Utiliser ILSPY Je peux voir que double.equals code> a une logique supplémentaire pour vérifier si l'une étant que la valeur comparée est NAN.

iLspy est également décompilé le corps de == code > À ceci: P>

public static bool operator ==(double left, double right)
{
    return left == right;
}


5 commentaires

Pas besoin d'utiliser ILSPY lorsque la source est disponible ici ici référencesSource.microsoft.com/ # MSCorlib / System / ...


@ Nighthawk441: Dans ce cas, non, mais en général ILSPY dispose de fonctionnalités de navigation et d'analyse utiles. C'est plus rapide que d'utiliser un site Web aussi. :)


Pourquoi avez-vous écrit "les autres opérateurs suivent le même modèle, qui est bizarre. Peut-être une erreur décompile?" Comme, qu'est-ce que tu voulais dire? Je suppose que vous pensiez que cela semblait redondant et que cela pourrait donc être une erreur de décompilation. On dirait que ce n'est pas une erreur de décompilation mais de conception. Mauvaise design.


Aussi je me demande si cette méthode si elle était exécutée serait infiniment récursive ?!


Exactement. Je soupçonne que nous examinons un comportement d'exécution de Code rigide spécifique aux types de données fondamentaux.



3
votes

Une raison possible est dû à la double.Nan.

pour le == opérateur : MSDN dit: Si deux valeurs doubles.Nan sont testées pour l'égalité à l'aide de l'opérateur d'égalité (==), le résultat est faux; Deux doubles valeurs ne sont pas considérées comme égales. S'ils sont testés pour l'égalité en appelant la méthode des égaux, le résultat est vrai. Lorsque vous souhaitez déterminer si la valeur d'un double n'est pas un nombre (NAN), une alternative consiste à appeler la méthode ISNAN.

de sorte que l'opérateur == et les méthodes de double double comportement ont des comportements différents. Doubler.Nan, je pense que c'est pourquoi == est remplacé par le double. Comme pour INT, il n'y a pas de tel cas particulier.

Le code à démo Les différences: xxx

Le code provient également de MSDN


6 commentaires

Pouvez-vous donner des échantillons de code compilables pour démontrer cette différence?


@TYCOBB référencesSource.microsoft.com/#mscorlib/system/double.cs# 155 semble ne pas fournir de raison utile de remplacer == cependant


Bien que cette explication explique Bool Bool Equals (Double OBJ) soit remplacé (comme le corps mentionne Nan), il n'explique pas pourquoi l'opérateur de Bool Statique public == est remplacé, car le corps de cette méthode == ne mentionne pas Nan. Et je demande à propos de la méthode ==. Donc, jusqu'à présent, la théorie de Tycobb semble plus forte.


@barlop, oui, tu as raison. Comme je suis allé à travers ce post par Jon Skeet: blogs.msdn.com/b/csharsfaq/archive/2004/03/29/... . Il dit: Pour les types de valeur, j'utiliserais normalement == pour un code plus facile à lire. Les choses deviennent difficiles si une valeur de valeur fournie une surcharge pour == qui a agi différemment pour égale, mais je considérerais un tel type très conçu pour commencer.


@Matt si si c'était le cas (théoriquement) que double n'a pas surchargé ==, il y avait toujours le problème qui se comporte différemment à ==. Parce que les angles sont surchargés et == n'est pas surchargé à égal. C'est comme s'ils pensaient peut-être qu'ils devraient surcharger pour correspondre à ce qu'il ait fait avec un code généré mais oublié de mettre en œuvre sanely (sain d'être, comme indique Sir Jon Skeet dans votre devis, == et.


@Matt selon 7.10.2 dans la spécification de langue C # 5.0 "Les opérateurs comparent les opérandes en fonction des règles de la norme IEEE 754" Il décrit ensuite des règles qui semblent un peu étranges, donc il peut donc être C'est pourquoi ils ont fait des angles différemment, ils l'ont fait leur chemin.



1
votes

int32 code> semble être très spécial en termes de .NET. La fonctionnalité qui manque à partir du code source est plus que probablement cuite au cœur du système.

Vous ne pouvez pas comparer les types de structs / valeurs avec == code>, > code> , etc. Sans déclarer ces opérateurs à l'intérieur de la structure. Parce que int32 code> est manquant, je suis arrivé à la conclusion ci-dessus. p>

Faites un test simple et de déversement de l'IL, ils effectuent exactement la même comparaison et aucun comparèteo code> ou est égal à code> est appelé (que je pensais réellement arrivé. J'ai appris quelque chose!). P>

public void TestInts()
{
    var x = 1;
    var y = 2;
    var equals = x == y;
}

.method public hidebysig 
    instance void TestInts () cil managed 
{
    // Method begins at RVA 0x2094
    // Code size 11 (0xb)
    .maxstack 2
    .locals init (
        [0] int32 x,
        [1] int32 y,
        [2] bool equals
    )

    IL_0000: nop
    IL_0001: ldc.i4.1
    IL_0002: stloc.0
    IL_0003: ldc.i4.2
    IL_0004: stloc.1
    IL_0005: ldloc.0
    IL_0006: ldloc.1
    IL_0007: ceq
    IL_0009: stloc.2
    IL_000a: ret
}

public void TestDoubles()
{
    var x = 1.7d;
    var y = 1.5d;
    var equals = x == y;
}
.method public hidebysig 
    instance void TestDoubles () cil managed 
{
    // Method begins at RVA 0x20ac
    // Code size 27 (0x1b)
    .maxstack 2
    .locals init (
        [0] float64 x,
        [1] float64 y,
        [2] bool equals
    )

    IL_0000: nop
    IL_0001: ldc.r8 1.7
    IL_000a: stloc.0
    IL_000b: ldc.r8 1.5
    IL_0014: stloc.1
    IL_0015: ldloc.0
    IL_0016: ldloc.1
    IL_0017: ceq
    IL_0019: stloc.2
    IL_001a: ret
}


5 commentaires

@barlop c'est une sorte de similaire. La seule prise en compte est la solution consiste à faire référence à l'égalité de référence qui est discutée en termes de types de valeur.


Je pense que vos commentaires ont répondu à la raison de ma question (votre théorie forte est bonne) .. Et vous avez fait un commentaire plus tôt que ma question (que vous avez supprimée), que si je me rappelle, impliquait (à juste titre) qu'il n'y a pas de ramification. (Vous l'avez supprimé car dans l'intérieur, vous avez rendu la réclamation erronée sur les .quensibles que vous corrigez dans votre réponse). Mais finalement, ce sont des commentaires des gens (y compris celui que vous avez supprimé qui aurait pu être le premier s'il est difficile de vérifier maintenant!), Qui a répondu à ma question.


bon point. Je pensais que cela l'utiliserait parce que j'ai figuré une instance de System.int32 est un objet? Les opérateurs de comparaison entier sont dans l'opérateur de 7.10.1 Bool == (int x, int y); Double est mentionné dans 7.10.2 Opérateur Bool == (double x, double y);


Bien repéré des nombres entiers dans votre édition. Donc, ils ne sont que dans les classes avec les NANs. D'ailleurs. System.Single est float.


@barlop Yea, j'ai décidé de nettoyer la maison sur mes commentaires parce qu'ils ne se sent plus bien. Je ne sais pas pourquoi j'ai giflé le flotteur là-bas quand j'avais célibataire. Va enlever.