web-dev-qa-db-fra.com

Quelle est la différence entre la diffusion et la conversion?

Les commentaires d'Eric Lippert dans cette question m'ont laissé complètement confus. Quelle est la différence entre la conversion et la conversion en C #?

68
Joel Spolsky

Je crois que ce que Eric essaie de dire est:

Casting est un terme décrivant la syntaxe (d'où le sens syntaxique ).

Conversion est un terme décrivant quelles actions sont réellement prises dans les coulisses (et donc la signification sémantique ).

Une expression cast est utilisée pour convertir explicitement une expression en un type donné.

Et

Une expression transtypée de la forme (T) E, où T est un type et E est une expression unaire, effectue une conversion explicite (§13.2) de la valeur de E en type T.

Semble sauvegarder cela en disant qu'un opérateur de transtypage dans la syntaxe effectue une conversion explicite.

45
Justin Niessner

La conversion est un moyen de dire au compilateur "L'objet X est vraiment de type Y, allez-y et traitez-le comme tel."

La conversion signifie "Je sais que l'objet X n'est pas de type Y, mais il existe un moyen de créer un nouvel objet à partir de X de type Y, allez-y et faites-le."

80
chrissr

Je me souviens de l'anecdote racontée par Richard Feynman où il suit un cours de philosophie et le professeur lui demande "Feynman, tu es physicien, à ton avis, l'électron est-il un" objet essentiel "?" Alors Feynman pose la question de clarification "la brique est-elle un objet essentiel?" à la classe. Chaque élève a une réponse différente à cette question. Ils disent que la notion abstraite fondamentale de la "brique" est l'objet essentiel. Non, une brique unique et spécifique est l'objet essentiel. Non, les parties de la brique que vous pouvez observer empiriquement sont l'objet essentiel. Etc.

Ce qui bien sûr ne répond pas à votre question.

Je ne vais pas parcourir toutes ces douzaines de réponses et débattre avec leurs auteurs de ce que je voulais vraiment dire. J'écrirai un article de blog sur le sujet dans quelques semaines et nous verrons si cela nous éclaire.

Que diriez-vous d'une analogie cependant, à la Feynman. Vous souhaitez faire cuire une miche de pain aux bananes samedi matin (comme je le fais presque tous les samedis matin). Vous consultez donc The Joy of Cooking, et il est écrit "bla bla bla ... Dans un autre bol, fouettez ensemble les ingrédients secs... .. "

Il y a clairement une relation forte entre cette instruction et vos actions de demain matin, mais il est tout aussi évident que ce serait une erreur de confondre la instruction avec la action. L'instruction se compose de texte. Il a un emplacement, sur une page particulière. Il y a de la ponctuation. Si vous étiez dans la cuisine en fouettant ensemble de la farine et du bicarbonate de soude, et que quelqu'un a demandé "quelle est votre ponctuation en ce moment?", Vous penseriez probablement que c'était une question étrange. L'action est liée à l'instruction, mais les propriétés textuelles de l'instruction ne sont pas des propriétés de l'action.

Un casting n'est pas une conversion de la même manière qu'une recette n'est pas l'acte de faire un gâteau. Une recette est un texte qui décrit une action, que vous pouvez ensuite effectuer. Un opérateur de transtypage est un texte qui décrit une action - une conversion - que le runtime peut ensuite effectuer.

42
Eric Lippert

De la spécification C # 14.6.6:

Une expression cast est utilisée pour convertir explicitement une expression en un type donné.
...
Une expression exprimée de la forme (T) E, où T est un type et E est une expression unaire, effectue une conversion explicite (§13.2) de la valeur de E en type T.

La conversion est donc une construction syntaxique utilisée pour demander au compilateur d'invoquer des conversions explicites.

De la spécification C # §13:

Une conversion permet de traiter une expression d'un type comme un autre type. Les conversions peuvent être implicites ou explicites, ce qui détermine si une conversion explicite est requise. [Exemple: Par exemple, la conversion de type int en type long est implicite, donc les expressions de type int peuvent implicitement être traitées comme type long. La conversion opposée, du type long au type int, est explicite, donc une conversion explicite est requise.

Les conversions sont donc l'endroit où le travail réel est effectué. Vous remarquerez que la citation de cast-expression indique qu'elle effectue des conversions explicites, mais les conversions explicites sont un surensemble de conversions implicites, vous pouvez donc également invoquer des conversions implicites (même si vous n'êtes pas obligé) via des cast-expressions.

7
Jason Punyon

Juste ma compréhension, probablement beaucoup trop simple:

Lors de la diffusion, les données essentielles restent intactes (même représentation interne) - "Je sais que c'est un dictionnaire, mais vous pouvez l'utiliser comme ICollection".

Lors de la conversion, vous changez la représentation interne en quelque chose d'autre - "Je veux que cet int soit une chaîne".

6
Oded

Après avoir lu les commentaires d'Eric, une tentative en anglais simple:

Casting signifie que les deux types sont en fait les mêmes à un certain niveau. Ils peuvent implémenter la même interface ou hériter de la même classe de base ou la cible peut être "suffisamment" (un sur-ensemble?) Pour que la conversion fonctionne, telle que la conversion d'Int16 en Int32.

Conversion types signifie alors que les deux objets peuvent être suffisamment similaires pour être convertis. Prenons par exemple une représentation sous forme de chaîne d'un nombre. Il s'agit d'une chaîne, elle ne peut pas simplement être convertie en un nombre, elle doit être analysée et convertie de l'un à l'autre et le processus peut échouer. Cela peut aussi échouer pour le casting, mais j'imagine que c'est un échec beaucoup moins cher.

Et c'est la principale différence entre les deux concepts, je pense. La conversion impliquera une sorte d'analyse, ou une analyse et une conversion plus approfondies des données source. Le casting n'analyse pas. Il tente simplement une correspondance à un certain niveau polymorphe.

5
Paul Sasik

Casting est la création d'une valeur d'un type à partir d'une autre valeur d'un autre type. Conversion est un type de transtypage dans lequel la représentation interne de la valeur doit également être modifiée (plutôt que juste son interprétation).

En C #, la conversion et la conversion sont toutes deux effectuées avec une expression de conversion :

( type ) expression unaire

La distinction est importante (et le point est fait dans le commentaire) car seules les conversions peuvent être créées par un opérateur-déclarateur de conversion . Par conséquent, seules les conversions (implicites ou explicites) peuvent être créées dans le code.

Une conversion implicite non-conversion est toujours disponible pour les transtypages de sous-type en supertype, et une conversion explicite non-conversion est toujours disponible pour les transtypages de supertype en sous-type. Aucune autre conversion sans conversion n'est autorisée.

2

Dans ce contexte, la conversion signifie que vous exposez un objet d'un type donné pour manipulation comme un autre type, la conversion signifie que vous changez réellement un objet d'un type donné en un objet d'un autre type.

1
heisenberg

Une distribution est syntaxique et peut impliquer ou non une conversion (selon le type de distribution). Comme vous le savez, C++ permet de spécifier le type de cast que vous souhaitez utiliser.

Le fait de monter/descendre la hiérarchie peut ou non être considéré comme une conversion, selon la personne à qui vous demandez (et la langue dont ils parlent!)

Eric (C #) dit que la conversion vers un type différent implique toujours une conversion, bien que cette conversion ne puisse même pas changer la représentation interne de l'instance.

Un gars en C++ - ne sera pas d'accord, car un static_cast pourrait ne pas générer de code supplémentaire (donc la "conversion" n'est pas réellement réelle!)

La conversion et la conversion sont fondamentalement le même concept en C #, sauf qu'une conversion peut être effectuée en utilisant n'importe quelle méthode telle que Object.ToString(). Le casting ne se fait qu'avec l'opérateur de casting (T) E, Qui est décrit dans d'autres articles, et peut utiliser des conversions ou de la boxe.

Quelle méthode de conversion utilise-t-elle? Le compilateur décide en fonction des classes et des bibliothèques fournies au compilateur au moment de la compilation. S'il existe une conversion implicite, vous n'êtes pas obligé d'utiliser l'opérateur de transtypage. Object o = String.Empty. S'il n'existe que des conversions explicites, vous devez utiliser l'opérateur de casting. String s = (String) o.

Vous pouvez créerexplicit et implicit opérateurs de conversion dans vos propres classes. Remarque: les conversions peuvent rendre les données très similaires ou rien du type d'origine pour vous et moi, mais elles sont toutes définies par les méthodes de conversion et les rendent légales pour le compilateur.

Casting toujours fait référence à l'utilisation de l'opérateur de casting. Tu peux écrire

Object o = float.NaN;
String s = (String) o;

Mais si vous accédez à s, par exemple dans un Console.WriteLine, Vous recevrez un runtime InvalidCastException. Ainsi, l'opérateur de distribution tente toujours d'utiliser la conversion au moment de l'accès, mais se contentera de la boxe lors de l'affectation.

0
maxwellb

Un cast est un opérateur sur une classe/structure. Une conversion est une méthode/un processus sur l'une ou l'autre des classes/structures affectées, ou peut être dans une classe/structure complètement différente (c'est-à-dire Converter.ToInt32()

Les opérateurs de distribution se présentent sous deux formes: implicite et explicite

Les opérateurs de transtypage implicites indiquent que les données d'un type (par exemple, Int32) peuvent toujours être représentées comme un autre type (décimal) sans perte de données/précision.

int i = 25;
decimal d = i;

Les opérateurs de transtypage explicites indiquent que les données d'un type (décimal) peuvent toujours être fidèlement représentées comme un autre type (int), mais il peut y avoir une perte de données/précision. Par conséquent, le compilateur vous oblige à explicitement déclarer que vous en êtes conscient et que vous voulez le faire de toute façon, en utilisant la syntaxe de conversion explicite:

decimal d = 25.0001;
int i = (int)d;

La conversion prend deux types qui ne sont pas nécessairement liés de quelque manière que ce soit, et tente de convertir l'un en l'autre par un processus, tel que l'analyse. Si tous les algorithmes de conversion connus échouent, le processus peut soit lever une exception, soit renvoyer une valeur par défaut:

string s = "200";
int i = Converter.ToInt32(s); // set i to 200 by parsing s

string s = "two hundred";
int i = Converter.ToInt32(s); // sets i to 0 because the parse fails

Les références d'Eric à la conversion syntaxique et à la conversion symétrique sont essentiellement une distinction opérateur/méthodologie.

0
Toby

Cette page de la documentation MSDN C # suggère qu'une conversion est une instance spécifique de conversion: la "conversion explicite". Autrement dit, une conversion de la forme x = (int)y est un transtypage.

Modifications automatiques du type de données (telles que myLong = myInt) sont la "conversion" la plus générique.

0
Dan Puzey