101 votes

Quelle est la difference entre casting et coercing?

J'ai vu les deux termes soient utilisés de manière presque interchangeable en ligne différents des explications, et la plupart des livres que j'ai consultés sont également pas tout à fait clair à propos de la distinction.

Est-il peut-être de façon claire et simple d'expliquer la différence que vous en savez?

La conversion de Type (connu également sous le nom de type cast)

Pour utiliser une valeur d'un type dans un contexte qui s'attend à une autre.

Nonconverting de type cast (parfois connu comme le type de jeu de mots)

Un changement qui ne modifie pas le sous-jacent bits.

La contrainte

Processus par lequel un compilateur convertit automatiquement une valeur d'un type en une valeur d'un autre type lors de ce second type est requise par le contexte environnant.

134voto

Igor Oks Points 9737

La Conversion De Type:

Le mot de conversion se réfère implicitement ou explicitement la modification d'une valeur d'un type de données à un autre, par exemple un entier 16 bits d'un entier de 32 bits.

Le mot de la coercition est utilisé pour indiquer une conversion implicite.

Le mot de fonte se réfère généralement à une conversion de type explicite (par opposition à une conversion implicite), indépendamment du fait que c'est une ré-interprétation d'un bit d'un motif ou d'une véritable conversion.

Donc, la contrainte est implicite, le casting est explicite, et la conversion est l'un d'eux.


Quelques exemples (à partir de la même source) :

La contrainte (implicite):

double  d;
int     i;
if (d > i)      d = i;

Cast (explicite):

double da = 3.3;
double db = 3.3;
double dc = 3.4;
int result = (int)da + (int)db + (int)dc; //result == 9

25voto

Eric Lippert Points 300275

Les Usages varient, comme vous le notez.

Mon utilisation est:

  • Un "casting" est l'utilisation d'un opérateur de cast. Un opérateur de cast indique au compilateur que soit (1) cette expression n'est pas connu pour être de type donné, mais je vous promets que la valeur de ce type lors de l'exécution; le compilateur est de traiter de l'expression comme étant d'un type donné, et l'exécution produira une erreur si elle n'est pas, ou (2) l'expression est d'un type différent entièrement, mais il ya une façon que l'on sait associer les instances de l'expression du type avec les instances de la fonte de type. Le compilateur est chargé de générer du code qui effectue la conversion. Le lecteur attentif remarquera que ce sont les opposés, je pense que c'est un truc intéressant.

  • Une "conversion" est une opération par laquelle une valeur d'un type est traité comme une valeur d'un autre type (généralement un type différent, mais d'une "identité de conversion" est toujours une conversion, techniquement parlant. La conversion peut être "la représentation de changer", comme int, double, ou il pourrait être "la préservation de la représentation" comme chaîne de caractères de l'objet. Les Conversions peuvent être "implicite", qui ne nécessitent pas un casting, ou "explicite", qui ne requièrent pas un plâtre.

  • Une "contrainte" est une représentation-évolution de la conversion implicite.

13voto

PedroC88 Points 1217

Le Casting est le processus par lequel vous traiter un type d'objet à un autre type, de Contraindre l'est de la conversion d'un objet à un autre.

Notez que dans l'ancien, il n'y a pas de conversion, vous avez un type que vous souhaitez traiter comme un autre, disons par exemple, vous disposez de 3 différents objets qui héritent d'un type de base, et vous avez une méthode qui va prendre ce type de base, à tout moment, si vous avez maintenant l'enfant en particulier, vous pouvez le convertir en ce qu'il est et d'utiliser toutes les méthodes et propriétés spécifiques de l'objet et qui ne va pas créer une nouvelle instance de l'objet.

D'autre part, le fait de contraindre implique la création d'un nouvel objet dans la mémoire du nouveau type, puis le type d'origine serait copié sur le nouveau, laissant à la fois des objets en mémoire (jusqu'à ce que les ramasseurs d'Ordures prend soit à l'écart, ou les deux).

1voto

Prisoner ZERO Points 3105

Ci-dessous est un détachement de l' article suivant:

La différence entre la contrainte et le casting est souvent négligé. Je peux voir pourquoi; de nombreuses langues ont le même (ou similaire) de la syntaxe et de la terminologie pour les deux opérations. Certaines langues peuvent même se référer à la conversion comme "casting", mais l'explication suivante fait référence à des notions dans le CTS.

Si vous essayez d'attribuer une valeur d'un type à l'emplacement d'un type différent, vous pouvez générer une valeur de type nouveau qui a un sens similaire à l'original. C'est la contrainte. La contrainte permet d'utiliser le nouveau type par la création d'une nouvelle valeur, qui ressemble à l'original. Certaines contraintes peuvent disposer de données (par exemple, la conversion de l'int 0x12345678 à court 0x5678), tandis que d'autres ne peuvent pas (par exemple, la conversion de l'int 0x00000008 à court 0x0008, ou le long 0x0000000000000008).

Rappelons que les valeurs peuvent avoir plusieurs types. Si votre situation est un peu différente, et que vous ne souhaitez sélectionner un autre de la valeur de types, le casting est l'outil pour le travail. Casting indique simplement que vous souhaitez utiliser sur un type qui a de la valeur.

La différence au niveau du code varie de C# à l'IL. En C#, à la fois de la coulée et de la coercition look assez similaire:

static void ChangeTypes(int number, System.IO.Stream stream)
{
    long longNumber = number;
    short shortNumber = (short)number;

    IDisposable disposableStream = stream;
    System.IO.FileStream fileStream = (System.IO.FileStream)stream;
}

Au niveau IL, ils sont très différents:

ldarg.0
 conv.i8
 stloc.0

ldarg.0
 conv.i2
 stloc.1


ldarg.1
 stloc.2

ldarg.1
 castclass [mscorlib]System.IO.FileStream
 stloc.3

Comme pour le niveau logique, il y a quelques différences importantes. Ce qui est le plus important à retenir est que la contrainte crée une nouvelle valeur, tandis que le casting n'est pas. L'identité de la valeur initiale et la valeur après la coulée sont les mêmes, alors que l'identité d'une contrainte valeur diffère de la valeur d'origine; encore de la contrainte crée une nouvelle, distincte exemple, alors que le casting n'est pas. Un corollaire est que le résultat du casting et de l'original sera toujours équivalent (à la fois de l'identité et de l'égalité), mais une contrainte de valeur peut ou peut ne pas être égale à l'original, et ne partage jamais l'identité d'origine.

Il est facile de voir les implications de la contrainte dans les exemples ci-dessus, comme les types numériques sont toujours copiés par valeur. Les choses deviennent un peu plus compliqué lorsque vous travaillez avec des types référence.

class Name : Tuple<string, string>
{
    public Name(string first, string last)
        : base(first, last)
    {
    }

    public static implicit operator string[](Name name)
    {
        return new string[] { name.Item1, name.Item2 };
    }
}

Dans l'exemple ci-dessous, une conversion est une fonte, tandis que l'autre est une contrainte.

Tuple<string, string> tuple = name;
string[] strings = name;

Après ces conversions, tuple et le nom de l'égalité, mais les cordes n'est pas égal à l'un d'eux. Vous pourrait rendre la situation un peu mieux (ou un peu plus de confusion) par la mise en œuvre de Equals() et operator ==() sur le Nom de la catégorie à comparer d'un Nom et d'un string[]. Ces opérateurs sont à "corriger" la comparaison de problème, mais vous auriez encore deux instances séparées; toute modification des chaînes ne seraient pas reflétés dans le nom ou le n-uplet, tandis que les changements apportés à l'un des nom ou le n-uplet serait le reflet de nom et de tuple, mais pas dans les cordes.

Bien que l'exemple ci-dessus était destiné à illustrer certaines différences entre la coulée et de la coercition, il sert également comme un excellent exemple de pourquoi vous devriez être très prudent sur l'utilisation d'opérateurs de conversion avec les types de référence en C#.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X