Eric Lippert's comments in this question have left me thoroughly confused. What is the difference between casting and conversion in C#?
-
3Maybe Eric's post sheds some more light on it: [Representation and Identity](http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx) – Dirk Vollmar Jul 02 '10 at 16:19
13 Answers
Casting is a way of telling the compiler "Object X is really Type Y, go ahead and treat it as such."
Conversion is saying "I know Object X isn't Type Y, but there exists a way of creating a new Object from X of Type Y, go ahead and do it."

- 9,861
- 2
- 29
- 30
-
8Great definition, but why then (int)5.5 is called a cast in C/C++ ? It is definitely a conversion. – Andrey Jul 02 '10 at 15:10
-
13
-
1Also what do you think about typical C# compilation error: "Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)" looks like everything gets mixed. – Andrey Jul 02 '10 at 15:13
-
2I would guess that the term "cast" has a bit of a muddy definition and usage. Casting primitives involves explicit conversion. It's only reference types where casting behaves as chrissr explained. Just doing this: `double a = 4.5; int b = a;` yields an accurate error message alluding to this: `Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)` ----- that's all in C#, I suspect C and C++ are the same story though. – Matt Greer Jul 02 '10 at 15:15
-
7I don't believe that this reflects the spirit of what Eric was trying to say. From my reading, he was not describing the behavior as "either `cast` or `convert`, but rather the *cast* being what's present in the code (in other words, the *cast operator*), where as *conversion* being what actually takes place. Very few conversions result in an identical in-memory representation (an example being casting between signed and unsigned versions of the same type, like `int` and `uint`, or casts to base types and interfaces). – Adam Robinson Jul 02 '10 at 15:18
-
Your answer is actually incorrect according to the MSDN documentation: `x = (int)y` where `y` is a `double` *is a cast*. (See the link in my answer.) – Dan Puzey Jul 02 '10 at 15:20
-
@Dan Puzey it is partially incorrect. his answer is valid for interfaces/base classes. – Andrey Jul 02 '10 at 15:35
-
@Matt I agree on the muddyness. The error message itself even says a conversion exists, but then suggests you use a cast to perform the conversion. `An explicit conversion exists (are you missing a cast?)` – AaronLS Jul 02 '10 at 15:36
-
@Andrey: you don't need an explicit conversion for that scenario - you can use implicit conversion (that is, if I have `List
myList` and then write `IEnumerable x = myList`, this is a valid *conversion* - I don't need to perform a cast with `IEnumerable x = (IEnumerable)myList`. – Dan Puzey Jul 02 '10 at 15:40 -
-
-
@Matt Greer: Converting primitives does not always involve use of the cast operator. For example I can write `int a = 4; long b = a;` with no problem because there is an implicit conversion from `int` to `long`. – Restore the Data Dumps Jul 02 '10 at 15:51
-
@Jason -- but you are still going against chrissr's answer. You have done a conversion (only this time it is implicit). The bottom line is casting just means different things for value types and reference types and requires some context to truly understand what it means to "cast". – Matt Greer Jul 02 '10 at 15:54
-
@Jason and @Matt: I'm not sure it's different for value vs. refence types - the difference in Jason's example is that the conversion is (by definition) lossless and can be done implicitly (as with, say, `string` to `object` assignment). A potentially lossy or failable conversion (like `long` to `int` or `object` to `string`) requires a cast operator. – Dan Puzey Jul 02 '10 at 16:07
-
3I would say that the distinction you are drawing is not casting vs conversion, but rather that of representation preserving conversions vs representation changing conversions. On the JScript team we made that distinction by calling the former "conversions" and the latter "coercions", but the distinction was pretty subtle. – Eric Lippert Jul 02 '10 at 16:52
-
This answer is misleading or incomplete because a conversion doesn't always exist (for a cast that requires it), and there can be a runtime exception. – Shelby Moore III Dec 16 '11 at 01:27
-
-
I don't know how correct would be this answer, as it is not language agnostic. For example in golang what you call, *casting* is called *assertion* https://go.dev/tour/methods/15 (and there is no transformaton at all). Also, in golang, *conversion*(https://go.dev/tour/basics/13) has another meaning that resembles the C *casting* (there is a transformation). I upvote this answer in the past, but today i believe https://stackoverflow.com/a/3166922/903998 is more correct and language agnostic and should be placed on top. – Victor Apr 26 '22 at 17:57
I believe what Eric is trying to say is:
Casting is a term describing syntax (hence the Syntactic meaning).
Conversion is a term describing what actions are actually taken behind the scenes (and thus the Semantic meaning).
A cast-expression is used to convert explicitly an expression to a given type.
And
A cast-expression of the form (T)E, where T is a type and E is a unary-expression, performs an explicit conversion (§13.2) of the value of E to type T.
Seems to back that up by saying that a cast operator in the syntax performs an explicit conversion.

- 242,243
- 40
- 408
- 536
-
4+1. So far the only answer I've seen that seems to pair up with what Eric was saying. – Adam Robinson Jul 02 '10 at 15:15
-
-
5No, I don't think that's what he meant. The syntax is called casting, but it doesn't always do a conversion behind the scenes. If you actually do a casting, there is no conversion going on. It might not even create any code at all, but only tell the compiler what type it should consider a reference to be. – Guffa Jul 02 '10 at 15:28
-
2In the context of the C# language, cast does mean this. In the context of IL, the `castclass` opcode has the meaning that others have described (interpret the reference as a different type.) So the 'cast operator' may resolve to either a cast or a conversion in the emitted IL. – Dan Bryant Jul 02 '10 at 15:29
-
7@Guffa: So what you are saying is that an "identity conversion" -- a conversion from, say, int to int -- is not a conversion? An interesting position but one not supported by the C# specification. – Eric Lippert Jul 02 '10 at 16:17
-
2Some conversions are just reinterpretations, some are not and require actual code behind the scenes to perform. Some conversions are done implicitly, others require an explicit cast. There's *no* correlation between the two statements above; some implicit conversions cause code to be generated, some explicit casts do not. However, (I believe that) all cases where the generated conversion can throw an exception require an explicit cast. – Donal Fellows Jul 02 '10 at 16:57
-
1@Donal: To be precise, the guidelines state that any conversion that could fail at runtime *or lose information* should require an explicit conversion. There isn't anything, however, that actually prevents an implicit conversion from throwing an exception. – Adam Robinson Jul 02 '10 at 17:19
-
1@Adam: though ideally implicit conversions do not lose information, some of the built-in implicit conversions do so. For example, when going between 64 bit integer and 64 bit float, bits of precision can be lost. The conversion does not lose *magnitude*, but it does lose *information*. – Eric Lippert Jul 02 '10 at 17:48
-
1@Eric: I hadn't thought of that scenario. While I can understand the desire not to make those explicit (since, conceptually but not practically, it's a widening conversion), doesn't that violate the "letter of the law", so to speak? – Adam Robinson Jul 02 '10 at 18:02
-
1@Adam: Yes, it is a bit of a violation to lose information in this manner. However, I think it's a reasonable exception to the general rule. If you are the sort of person who does math in doubles then you are already the sort of person willing to take on rounding errors. – Eric Lippert Jul 02 '10 at 18:26
-
@Eric: Yeah, I think it's reasonable too, especially given (as you point out) the approximated nature of floating point numbers anyway. – Adam Robinson Jul 02 '10 at 18:29
-
1
-
I upvote this answer as it mix the concepts (casting and conversion) in a more correct way. For example, In ,C we could make this https://onlinegdb.com/vYTe5sqMG, that is a **cast** (changing explicity the type of an expression) and also a **conversion** (doing the work of transforming the bits of a floating point to the bits of a signed interger). As i see things the bottom line is: *a casting not always (but often) implies a conversion (or transformation process) and a conversion do implies a casting*. Please, anyone reading this, feel free to validate my thoughts. – Victor Apr 26 '22 at 18:10
I am reminded of the anecdote told by Richard Feynman where he is attending a philosophy class and the professor askes him "Feynman, you're a physicist, in your opinion is an electron an 'essential object'?" So Feynman asks the clarifying question "is a brick an essential object?" to the class. Every student has a different answer to that question. They say that the fundamental abstract notion of "brickness" is the essential object. No, one specific, unique brick is the essential object. No, the parts of the brick you can empirically observe is the essential object. And so on.
Which is of course not to answer your question.
I'm not going to go through all these dozen answers and debate with their authors about what I really meant. I'll write a blog article on the subject in a few weeks and we'll see if that throws any light on the matter.
How about an analogy though, a la Feynman. You wish to bake a loaf of banana bread Saturday morning (as I do almost every Saturday morning.) So you consult The Joy of Cooking, and it says "blah blah blah... In another bowl, whisk together the dry ingredients. ..."
Clearly there is a strong relationship between that instruction and your actions tomorrow morning, but equally clearly it would be a mistake to conflate the instruction with the action. The instruction consists of text. It has a location, on a particular page. It has punctuation. Were you to be in the kitchen whisking together flour and baking soda, and someone asked "what's your punctuation right now?", you'd probably think it was an odd question. The action is related to the instruction, but the textual properties of the instruction are not properties of the action.
A cast is not a conversion in the same way that a recipe is not the act of baking a cake. A recipe is text which describes an action, which you can then perform. A cast operator is text which describes an action - a conversion - which the runtime can then perform.

- 647,829
- 179
- 1,238
- 2,067
-
-
7Part of me wonders what it is like to work with Eric. The other part hopes I didn't butcher his meaning too much in my post. – Justin Niessner Jul 02 '10 at 17:36
-
Or more simply stated, a cast can be erased at compile-time; whereas, a conversion requires some action at runtime. For example, a cast is sometimes necessary to tell the compiler what type you wish it to infer, for languages that do type inference. – Shelby Moore III Dec 09 '11 at 18:16
-
@AndrewBarber it is a fact that a cast does erasure (don't confuse this with type erasure). This means that its effect is only at compile-time and there is no runtime code to convert the physical object. [Wikipedia says](http://en.wikipedia.org/wiki/Type_conversion), "cast, refers to explicitly changing the interpretation of the bit pattern representing a value from one type to another. For example 32 contiguous bits may be treated as an array of 32 booleans, a 2 char Unicode string, an unsigned 32-bit int or IEEE single precision float. While the storage requirements are never changed" – Shelby Moore III Dec 10 '11 at 06:53
-
-
@Shog9 So now you know why Joel is confused. C# is redefining the standard meaning of "casting". Nevertheless, the meaning of "casting" is the definition I gave, no matter which language you are using. MSFT can call a "car" a "lemon", and it will still be a car. Reality is hard to ignore. Actually I vaguely remember a public discussion about this in C or C++ days in a discussion group afair, and it was admitted that this was error that caught on and was hard to stop. It was stated that this was incorrect and unfortunate. I will try to dig that up with Google. – Shelby Moore III Dec 10 '11 at 20:27
-
1And in C#, a List is an array... Life is full of such interesting nomenclature discussions, @Shelby - but if you choose to while away the hours engaged in such things, I must ask that you do so [in chat](http://chat.stackoverflow.com/rooms/7/c). – Shog9 Dec 10 '11 at 20:33
-
@Shog9, I clicked the chat link, and I don't find you there? I want to ask clearly, are you saying I cannot respond here any more? I found this [document on C++](http://books.google.com.ph/books?id=3fPEuyxmsW4C&lpg=PA90&ots=_08x0ranZ1&dq=K%20%26%20R%20C%20type%20cast&pg=PA91#v=onepage&q=K%20&%20R%20C%20type%20cast&f=false), and it seems to show they admitted the conflation error and tried to migrate away from it by making the conversion operator look like a function call, e.g. `typename (value)` instead of C's `(typename) value`-- mentions unification with user-defined conversion. – Shelby Moore III Dec 10 '11 at 20:45
-
@Shog9 I think Eric is saying the same thing I am. What if his promised blog on this subject ends up confirming what I wrote? Eric wrote, "A cast is not a conversion in the same way that a recipe is not the act of baking a cake. A recipe is text which describes an action, which you can then perform. A cast operator is text which describes an action - a conversion - which the runtime can then perform." Are you saying that Eric Lippert is wrong? – Shelby Moore III Dec 10 '11 at 20:58
-
1@Shelby: I'm busy doing housework, but you should be able to find some of the C# regulars in chat sooner or later. And yeah, you should stop responding here - the resemblance of C#'s syntax and terminology to C++ are mostly superficial, and trying to answer a question like this with comparisons to other languages tends to just end up confusing people. [*This* question might benefit from some historical background however](http://stackoverflow.com/questions/4337306/type-conversion-casting-confusion-in-c). – Shog9 Dec 10 '11 at 21:00
-
@Shoq9 I am finished here, as long as you don't delete my comments. Thanks for providing the link on the historical background. Let's wait for Eric to blog on this. – Shelby Moore III Dec 10 '11 at 21:09
-
The more I think about this, I realize this answer is wrong, because it implies that cast always results in a conversion (the same mistake made by the MSDN docs). I clearly showed examples of (even explicit) casts in my answer, which do not result in conversions. Sadly I find all the most voted answers on this page are wrong. Sorry but that is my opinion. – Shelby Moore III Dec 16 '11 at 01:29
-
2@ShelbyMooreIII: Of course a cast always results in a conversion. **An identity conversion is a conversion.** But you are of course free to disagree. I see you've written your own answer that explains your position. – Eric Lippert Dec 16 '11 at 04:13
-
@Eric thanks for the clarification. I haven't been able to find that definition of the word _conversion_ in Merriam-Websters or other English dictionaries. They all seem to require that something actually changes. And then upcasting is not a conversion, unless you are saying a conversion of representation at the syntax layer of semantics. Conflating cast and conversion doesn't seem to work, bcz they are occurring at different semantic layers of abstraction, cast at the compile-time type system and conversion at the runtime representation. Any way, maybe there is more than 1 way to skin a cat. – Shelby Moore III Dec 16 '11 at 23:44
-
4@ShelbyMooreIII: You won't find "struct", "readonly" or "stackalloc" in M-W either. I'm not sure why M-W definitions are relevant; the relevant definition of "conversion" is in the C# specification. A conversion need not change anything, just as an addition of one number to another need not change either; zero is the additive identity. The identity conversion is similarly a conversion that does not change anything. But yes, you seem to have grasped my point: the cast operator is a textual artifact that instructs the compiler to generate code that performs a conversion. – Eric Lippert Dec 17 '11 at 03:33
-
@Eric Explicit downcasts can result in an exception thus no conversion. "Failed conversion"? Perhaps a comp sci & math term for conversion that doesn't always change something (i.e. includes identity), is _[morphism](http://en.wikipedia.org/wiki/Morphism)_. [Wikipedia](http://en.wikipedia.org/wiki/Type_conversion) says about type conversion in general "change", and "re-intepretation … or … real" w.r.t. C#. [Computing uses](http://en.wikipedia.org/wiki/Conversion#Computing) of conversion imply change. Agreed, cast is a textual artifact morphism. "Artifact" is more comprehensible than "erasure". – Shelby Moore III Dec 17 '11 at 17:54
-
@Eric An upcast from `Giraffe` to `Animal` causes a _change_ in type representation at the semantic layer of the language layer type system (i.e. the abstraction level of denotational semantics, where ["Theorems are for free"](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf)). But the conversion at runtime can be an identity, because the in-memory representation may not change (at the operational semantics layer of abstraction). Cast change doesn't always cause a conversion change. Casts are morphisms at a different abstraction layer than conversions. **The two are not surjective.** – Shelby Moore III Dec 17 '11 at 19:22
-
1@AndrewBarber: We're all here to learn. And I think that Shelby and I pretty much agree on the concepts; as you say, the argument, assuming there is one, seems to be about definitions. – Eric Lippert Dec 18 '11 at 15:48
-
nice answer, though the comment I found says "No, it is explicit conversion. You are confusing explicit and implicit casting with explicit and implicit conversion. Implicit casts are extremely rare in C#; the only time people commonly come across an implicit use of the cast operator is in the foreach loop," And I am still confused by the term "Implicit cast", I suppose its a C# thing, that some transformations on the level of code are made, such that some cast is in the code, but only implicitly – 463035818_is_not_an_ai Jan 31 '23 at 14:07
-
@463035818_is_not_a_number: The C# specification says that `foreach(X x in xs)` fetches the value of `x` by getting an enumerator from `xs` and pretending that the user actually wrote `X x = (X)e.Current;` in the body of the loop; see the specification for the exact details. The point is, this is one of the very few places in C# where the compiler does cast *semantics* without a cast *operator* being actually in the source code text. – Eric Lippert Jan 31 '23 at 16:16
-
@463035818_is_not_a_number: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#1295-the-foreach-statement – Eric Lippert Jan 31 '23 at 16:18
-
thanks. I suppose it is very similar to c++s range based for loop, which is short hand for some code that is then just *implicit* – 463035818_is_not_an_ai Jan 31 '23 at 19:15
From the C# Spec 14.6.6:
A cast-expression is used to convert explicitly an expression to a given type.
...
A cast-expression of the form (T)E, where T is a type and E is a unary-expression, performs an explicit conversion (§13.2) of the value of E to type T.
So casting is a syntactic construct used to instruct the compiler to invoke explicit conversions.
From the C# Spec §13:
A conversion enables an expression of one type to be treated as another type. Conversions can be implicit or explicit, and this determines whether an explicit cast is required. [Example: For instance, the conversion from type int to type long is implicit, so expressions of type int can implicitly be treated as type long. The opposite conversion, from type long to type int, is explicit, so an explicit cast is required.
So conversions are where the actual work gets done. You'll note that the cast-expression quote says that it performs explicit conversions but explicit conversions are a superset of implicit conversions, so you can also invoke implicit conversions (even if you don't have to) via cast-expressions.

- 38,967
- 12
- 96
- 122
-
...among other things. The casting syntax can also be used to instruct the compiler to do a casting. – Guffa Jul 02 '10 at 15:30
-
@Guffa: Do you have a reference for that? There are only 5 instances of the word "casting" in the body of the C# spec and none of those instances define anything... – Restore the Data Dumps Jul 02 '10 at 15:40
Just my understanding, probably much too simple:
When casting the essential data remains intact (same internal representation) - "I know this is a dictionary, but you can use it as a ICollection".
When converting, you are changing the internal representation to something else - "I want this int to be a string".

- 489,969
- 99
- 883
- 1,009
-
A cast from a short to an int in C# also causes a conversion (2 bytes to 4 bytes). Only casts up or down an reference-type object heirarachy do not cause conversions. – Jeffrey L Whitledge Jul 02 '10 at 15:30
-
1What you describe as a casting is actually a widening conversion. http://msdn.microsoft.com/en-us/library/k1e94s7e%28VS.80%29.aspx – Guffa Jul 02 '10 at 15:33
-
@Jeffrey L Whitledge, @Guffa - thanks for the correction. Answer updated. – Oded Jul 02 '10 at 15:37
After reading Eric's comments, an attempt in plain english:
Casting means that the two types are actually the same at some level. They may implement the same interface or inherit from the same base class or the target can be "same enough" (a superset?) for the cast to work such as casting from Int16 to Int32.
Converting types then means that the two objects may be similar enough to be converted. Take for example a string representation of a number. It is a string, it cannot simply be cast into a number, it needs to be parsed and converted from one to the other, and, the process may fail. It may fail for casting as well but I imagine that's a much less expensive failure.
And that's the key difference between the two concepts I think. Conversion will entail some sort of parsing, or deeper analysis and conversion of the source data. Casting does not parse. It simply attempts a match at some polymorphic level.

- 79,492
- 20
- 149
- 189
Casting is the creation of a value of one type from another value of another type. Conversion is a type of casting in which the internal representation of the value must also be changed (rather than just its interpretation).
In C#, casting and converting are both done with a cast-expression:
( type ) unary-expression
The distinction is important (and the point is made in the comment) because only conversions may be created by a conversion-operator-declarator. Therefore, only (implicit or explicit) conversions may be created in code.
A non-conversion implicit cast is always available for subtype-to-supertype casts, and a non-conversion explicit cast is always available for supertype-to-subtype casts. No other non-conversion casts are allowed.

- 58,241
- 9
- 71
- 99
In this context, casting means that you are exposing an object of a given type for manipulation as some other type, conversion means that you are actually changing an object of a given type to an object of another type.

- 9,665
- 1
- 30
- 38
This page of the MSDN C# documentation suggests that a cast is specific instance of conversion: the "explicit conversion." That is, a conversion of the form x = (int)y
is a cast.
Automatic data type changes (such as myLong = myInt
) are the more generic "conversion."

- 33,626
- 4
- 73
- 96
-
1No, it doesn't suggest that a cast is a type of conversion, it says that in order to perform an explicit conversion, a cast (specifically, the use of the *cast operator*) is required. Casting is a *language instruction*, not *an operation* that's distinct from conversion. – Adam Robinson Jul 02 '10 at 15:23
-
True; the page suggests that the casting operator is required for explicit conversion, and that this is required if any data might be lost in the conversion. So yes, technically casting is the operation that *performs* a type of coversion, but I think my answer is still closer to the truth than the current top-voted one (which contradicts the documentation entirely). Jason Punyon's answer gets my vote! – Dan Puzey Jul 02 '10 at 15:32
-
@Adam I say you and Dan are both slightly confused. Casting is an operation that happens at the denotational semantics layer (where types are expressed in their full semantics). A cast may or may not (e.g. upcasting) cause a conversion at the runtime semantic layer. You see all the downvotes on my answer indicates most people don't understand the differences between [denotational semantics and operational (execution) semantics](http://en.wikipedia.org/wiki/Semantics_of_programming_languages). – Shelby Moore III Dec 14 '11 at 10:13
-
2@ShelbyMooreIII: I think the downvotes on your answer indicate that your answer is a) too long b) not very clear and c) not specific to the question. The question is referring to the C# language, not to compiler theory in general, and I'm happy to agree that the two may use terms differently. The fact that you've made 7 extensive edits and still the debate rages on (with some of the smartest minds on this site) would suggest that it's not me who is confused. This is a question that was deemed "answered" five months ago! – Dan Puzey Dec 14 '11 at 11:43
-
@DanPuzey Well said. I think much of what Shelby has said here and there is true enough, usually; but he's just not doing a good job at all of *answering the question posed*. – Andrew Barber Dec 15 '11 at 04:55
-
@DanPuzey The chosen answer (Justin's) is wrong. Conversion isn't the semantic meaning. chrissr's answer is misleading or incomplete because a conversion doesn't always exist, and there can be a runtime exception. Eric Lippert's answer is wrong, because it implies that cast always results in a conversion (the same mistake made by the MSDN docs). So now you know why I answered the question and I did provide the correct answer for C#, which also happens to the correct answer for all languages. Yeah apparently very many people are confused, they can't even be taught the correct answer. Big heads. – Shelby Moore III Dec 16 '11 at 01:23
-
1@ShelbyMooreIII Clearly, you know so much more about the C# language that *everyone else*, including one of the primary developers on the C# compiler team. `` – Andrew Barber Dec 18 '11 at 05:21
A cast is an operator on a class/struct. A conversion is a method/process on one or the other of the affected classes/structs, or may be in a complete different class/struct (i.e. Converter.ToInt32()
Cast operators come in two flavors: implicit and explicit
Implicit cast operators indicate that data of one type (say, Int32) can always be represented as another type (decimal) without loss of data/precision.
int i = 25;
decimal d = i;
Explicit cast operators indicate that data of one type (decimal) can always be faithfully represented as another type (int), but there may be loss of data/precision. Therefor the compiler requires you to explicitly state that you are aware of this and want to do it anyway, through use of the explicit cast syntax:
decimal d = 25.0001;
int i = (int)d;
Conversion takes two types that are not necessarily related in any way, and attempts to convert one into the other through some process, such as parsing. If all known conversion algorithms fail, the process may either throw an exception or return a default value:
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
Eric's references to syntactic conversion vs. symantic conversion are basically an operator vs. methodology distinction.

- 7,354
- 3
- 25
- 26
A cast is syntactical, and may or may not involve a conversion (depending on the type of cast). As you know, C++ allows specifying the type of cast you want to use.
Casting up/down the hierarchy may or may not be considered conversion, depending on who you ask (and what language they're talking about!)
Eric (C#) is saying that casting to a different type always involves a conversion, though that conversion may not even change the internal representation of the instance.
A C++-guy will disagree, since a static_cast
might not result in any extra code (so the "conversion" is not actually real!)

- 1
- 1

- 84,206
- 33
- 197
- 283
Casting and Conversion are basically the same concept in C#, except that a conversion may be done using any method such as Object.ToString()
. Casting is only done with the casting operator (T) E
, that is described in other posts, and may make use of conversions or boxing.
Which conversion method does it use? The compiler decides based on the classes and libraries provided to the compiler at compile-time. If an implicit conversion exists, you are not required to use the casting operator. Object o = String.Empty
. If only explicit conversions exist, you must use the casting operator. String s = (String) o
.
You can create explicit
and implicit
conversion operators in your own classes. Note: conversions can make the data look very similar or nothing like the original type to you and me, but it's all defined by the conversion methods, and makes it legal to the compiler.
Casting always refers to the use of the casting operator. You can write
Object o = float.NaN;
String s = (String) o;
But if you access s
, in for example a Console.WriteLine
, you will receive a runtime InvalidCastException
. So, the cast operator still attempts to use conversion at access time, but will settle for boxing during assignment.

- 13,366
- 2
- 25
- 35
INSERTED EDIT#2: isn't it hilariously inconsistent myopia that since I provided this answer, the question has been marked as duplicate of a question which asks, "Is casting the same thing as converting?". And the answers of "No" are overwhelmingly upvoted. Yet my answer here which points out the generative essence for why casts are not the same as conversion is overwhelmingly downvoted (yet I have one +1 in the comments). I suppose that readers have a difficult time with comprehending that casts apply at the denotational syntax/semantics layer and conversions apply at the operational semantics layer. For example, a cast of a reference (or pointer in C/C++)—referring to a boxed data type—to another data type, doesn't (in all languages and scenarios) generate a conversion of the boxed data. For example, in C float a[1]; int* p = (int*)&a;
doesn't insure that *p
refers to int
data.
A compiler compiles from denotational semantics to operational semantics. The compilation is not bijective, i.e. it isn't guaranteed to uncompile (e.g. Java, LLVM, asm.js, or C# bytecode) back to any denotational syntax which compiles to that bytecode (e.g. Scala, Python, C#, C via Emscripten, etc). Thus the two layers not the same.
Thus most obviously a 'cast' and a 'conversion' are not the same thing. My answer here is pointing out that the terms apply to two different layers of semantics. Casts apply to the semantics of what the denotational layer (input syntax of the compiler) knows about. Conversions apply to the semantics of what the operational (runtime or intermediate bytecode) layer knows about. I used the standard term of 'erased' to describe what happens to denotational semantics that aren't explicitly recorded in the operational semantics layer.
For example, reified generics are an example of recording denotational semantics in the operational semantics layer, but they have the disadvantage of making the operational semantics layer incompatible with higher-order denotational semantics, e.g. this is why it was painful to consider implementing Scala's higher-kinded generics on C#'s CLR because C#'s denotational semantics for generics was hard-coded at the operational semantics layer.
Come on guys, stop downvoting someone who knows a lot more than you do. Do your homework first before you vote.
INSERTED EDIT: Casting is an operation that happens at the denotational semantics layer (where types are expressed in their full semantics). A cast may (e.g. explicit conversion) or may not (e.g. upcasting) cause a conversion at the runtime semantic layer. The downvotes on my answer (and the upvoting on Marc Gavin's comment) indicates to me that most people don't understand the differences between denotational semantics and operational (execution) semantics. Sigh.
I will state Eric Lippert's answer more simply and more generally for all languages, including C#.
A cast is syntax so (like all syntax) is erased at compile-time; whereas, a conversion causes some action at runtime.
That is a true statement for every computer language that I am aware of in the entire universe. Note that the above statement does not say that casting and conversions are mutually exclusive.
A cast may cause a conversion at runtime, but there are cases where it may not.
The reason we have two distinct words, i.e. cast and conversion, is we need a way to separately describe what is happening in syntax (the cast operator) and at runtime (conversion, or type check and possible conversion).
It is important that we maintain this separation-of-concepts, because in some programming languages the cast never causes a conversion. Also so that we understand implicit casting (e.g. upcasting) is happening only at compile-time. The reason I wrote this answer is because I want to help readers understand in terms of being multilingual with computer languages. And also to see how that general definition correctly applies in the C# case as well.
Also I wanted to help readers see how I generalize concepts in my mind, which helps me as computer language designer. I am trying to pass along the gift of a very reductionist, abstract way of thinking. But I am also trying to explain this in a very practical way. Please feel free to let me know in the comments if I need to improve the elucidation.
Eric Lippert wrote:
A cast is not a conversion in the same way that a recipe is not the act of baking a cake. A recipe is text which describes an action, which you can then perform. A cast operator is text which describes an action - a conversion - which the runtime can then perform.
The recipe is what is happening in syntax. Syntax is always erased, and replaced with either nothing or some runtime code.
For example, I can write a cast in C# that does nothing and is entirely erased at compile-time when it is does not cause a change in the storage requirements or is upcasting. We can clearly see that a cast is just syntax, that makes no change to the runtime code.
int x = 1;
int y = (int)x;
Giraffe g = new Giraffe();
Animal a = (Animal)g;
That can be used for documentation purposes (yet noisy), but it is essential in languages that have type inference, where a cast is sometimes necessary to tell the compiler what type you wish it to infer.
For an example, in Scala a None
has the type Option[Nothing]
where Nothing
is the bottom type that is the sub-type of all possible types (not super-type). So sometimes when using None, the type needs to be casted to a specific type, because Scala only does local type inference, thus can't always infer the type you intended.
// (None : Option[Int]) casts None to Option[Int]
println(Some(7) <*> ((None : Option[Int]) <*> (Some(9) > add)))
A cast could know at compile-time that it requires a type conversion, e.g. int x = (int)1.5
, or could require a type check and possible type conversion at runtime, e.g. downcasting. The cast (i.e. the syntax) is erased and replaced with the runtime action.
Thus we can clearly see that equating all casts with explicit conversion, is an error of implication in the MSDN documentation. That documentation is intending to say that explicit conversion requires a cast operator, but it should not be trying to also imply that all casts are explicit conversions. I am confident that Eric Lippert can clear this up when he writes the blog he promised in his answer.
ADD: From the comments and chat, I can see that there is some confusion about the meaning of the term erased.
The term 'erased' is used to describe information that was known at compile-time, which is not known at runtime. For example, types can be erased in non-reified generics, and it is called type erasure.
Generally speaking all the syntax is erased, because generally CLI is not bijective (invertible, and one-to-one) with C#. You cannot always go backwards from some arbitrary CLI code back to the exact C# source code. This means information has been erased.
Those who say erased is not the right term, are conflating the implementation of a cast with the semantic of the cast. The cast is a higher-level semantic (I think it is actually higher than syntax, it is denotational semantics at least in case of upcasting and downcasting) that says at that level of semantics that we want to cast the type. Now how that gets done at runtime is entirely different level of semantics. In some languages it might always be a NOOP. For example, in Haskell all typing information is erased at compile-time.

- 1
- 1

- 6,063
- 1
- 33
- 36
-
6I don't think this is really restating Eric's answer. Claiming that a cast is "erased at compile-time" suggests it has no meaning. *Sometimes* that will be true (sometimes the cast will not require any action) but usually it's not true (it requires the compiler to emit IL to execute the conversion at execution time). If you're going to talk about even a cast requiring conversion being "erased" then the term becomes meaningless - because *all* the source code is presumably "erased" by the compiler. I believe that the use of the term "erase" does more to confuse than enlighten here. – Jon Skeet Dec 11 '11 at 18:19
-
3(I think it would be clearer to say that a cast may or may not be *translated* by the compiler into code which will cause a conversion at execution time.) – Jon Skeet Dec 11 '11 at 18:54
-
4The `Animal`/`Giraffe` example is a bad one; now imagine: `Animal a = new Dog(); Giraffe g = (Giraffe)a;` That is most definitely **not** erased at compile time, and is not a conversion (nothing is changed; nothing is converted; this is a reference-preserving operation) - a `castclass` opcode is produced, which is a **runtime** operation to do a type check. While a cast **can** sometimes be removed by the compiler (if it is clearly always true), that doesn't mean it is **always** removed, thus it is not true to say that a "cast **is** erased at compile-time" (emphasis mine). – Marc Gravell Dec 11 '11 at 19:43
-
1Downvoting publicly, openly and with my name on it (since you seem to value that) for the simple reason that the statement is incorrect and misleading. – Marc Gravell Dec 11 '11 at 19:48
-
@JonSkeet that is why it is so important to include the Scala code sample. Because there are cases where a cast w/o conversion has a meaning. A cast is really orthogonal to conversion, as proven by the C# code sample in my answer. I know it is shocking but there it is in front of your eyes. That is what Eric and others are saying. Cast is just at compile-time. Now it sometimes causes conversion. But sometimes it does not. Can you ask Eric please? – Shelby Moore III Dec 11 '11 at 21:19
-
@JonSkeet there are languages where a cast is never converted to conversion. So it is not good to think about cast the way you want to. It will lead to problems when becoming multilingual, which every programmer must do these days. – Shelby Moore III Dec 11 '11 at 21:21
-
@MarcGravell You are confusing upcasting and downcasting. Please refer to the links I provided in my answer. Sorry your downvote is erroneous. I hope you remove it. Thanks for being open. I am not trying to start negative feelings. Thanks for asking me for clarification. – Shelby Moore III Dec 11 '11 at 21:24
-
2@Shelby no, I'm not confusing anything. I am simply disputing your claim "A cast is erased at compile-time". Not always it isn't. It is still a cast, no matter the direction. – Marc Gravell Dec 11 '11 at 21:28
-
@MarcGravell Please I am not trying to fight with you. But your example is downcasting. Cast does not require a conversion with upcasting. – Shelby Moore III Dec 11 '11 at 21:29
-
@MarcGravell If cast is not erased, then what is the difference between conversion and cast? You tell me? Would you prefer that I write that cast is only erased when it does not cause a conversion? But is the cast in the runtime or is the conversion in the runtime? You see precision is very important in Comp sci. Do you know I am creating a language. So it is very important that I be precise or the language won't work. – Shelby Moore III Dec 11 '11 at 21:32
-
@MarcGravell In my answer I did not say that downcasting requires a conversion. I said it may cause a conversion at runtime. It requires checking for a conversion at runtime. – Shelby Moore III Dec 11 '11 at 21:38
-
@MarcGravell The cast always causes a type check. It is just that sometimes the type check is done at compile-time and other cases at runtime. A type check and conversion are not a cast. The cast is what is in the syntax. The top voted answer says that. – Shelby Moore III Dec 11 '11 at 21:40
-
1@ShelbyMooreIII If it may cause a type check and conversion at runtime then it is *not* erased. I don't know what your argument is. Saying that it is erased implies that results in it doing nothing whatsoever at runtime. – quantumSoup Dec 11 '11 at 21:41
-
@quantumSoup The syntax is erased at compile-time. You are left with the runtime code. The cast is only syntax. We don't want to combine things that are different things. The cast is the compile-time operator. It erased and it may cause a runtime action. That runtime action is called a conversion. The reason it is important to separate the concepts, is because in some languages a cast can never be a conversion. So then one would ask why did you tell me that a cast is a conversion? So to make them separate concepts, the cast is the syntax portion only. Refer to the top voted answer as proof. – Shelby Moore III Dec 11 '11 at 21:44
-
@quantumSoup See Eric Lippert's answer also. He is explaining that the cast is only the recipe, i.e. the syntax. And confirmed by the top voted answer also. – Shelby Moore III Dec 11 '11 at 21:47
-
4@ShelbyMooreIII sigh - this really is getting tedious; conversions are just one thing that might result from a cast. Your point about removed at compile time is meaningless, as **that is the point of a compiler**; almost all code (except certain dynamic/lambda etc) is removed! that statement adds nothing and is empty. Most casts, however, do not have anything whatsoever to do with conversion. There is no conversion in an upcast or downcast, or casting between an interface and a class. That says NOTHING about whether something happens (or doesn't happen) at runtime. – Marc Gravell Dec 11 '11 at 21:47
-
2@ShelbyMooreIII I think I get you are getting at. But if that's your definition of "erased", then all **all** syntax is "erased" at compile-time. – quantumSoup Dec 11 '11 at 21:47
-
7Seriously, with the number of people pointing out fundamental problems in so many of your answers on this topic - do you think that *maybe, just maybe* the problem is in either your *understanding*, or your *explanation* ? – Marc Gravell Dec 11 '11 at 21:49
-
@quantumSoup all syntax is erased at compile-time. The reason we needed a separate term for cast and conversion, is because we needed a term to describe the syntax portion only, i.e. cast. We needed that because in some languages a cast does not cause a conversion. Let me know if that is still confusing? – Shelby Moore III Dec 11 '11 at 21:50
-
@MarcGravell See my answer to quantumSoup. Do you understand now? Or is it still confusing? – Shelby Moore III Dec 11 '11 at 21:51
-
Thanks guys for the feedback. I see I need to improve the answer. Does my last comment explain it? – Shelby Moore III Dec 11 '11 at 21:52
-
2@Shelby I am not confused - I just (strongly) disagree with the answer presented. There's a difference. In particular, it over-generalises (uses a specific scenario that claims to prove a more general statement, that is actually not true), and you are focusing *way too much* on conversions, when that isn't what is being discussed. – Marc Gravell Dec 11 '11 at 21:54
-
@MarcGravell the title of the question is, "What is the difference between casting and conversion?". Can you explain what you mean? – Shelby Moore III Dec 11 '11 at 21:56
-
@MarcGravell Please come to chat. I want to discuss with you. – Shelby Moore III Dec 11 '11 at 21:57
-
1(error occurred moving to chat). In all honesty, I think the main problem is the statement "A cast is erased at compile-time; whereas, a conversion causes some action at runtime". The first half is irrelevant, since virtually all code is "erased at compile-time"; the second is incorrect in that it is not necessary that the result is "some action" at runtime. With that, there is also the 3 different definitions of conversion, without clarity (reference-preserving, value-changing (custom and inbuilt), and syntactic), and 2 different cast meanings (syntactic vs CLI). The answer ... – Marc Gravell Dec 11 '11 at 22:06
-
2is simply unclear what it is using in each case. Don't get me wrong - it is a really hard topic to get exactly right - I just don't think this answer gets as close to it as many of the existing answers, but risks adding much confusion. – Marc Gravell Dec 11 '11 at 22:08
-
@MarcGravell Okay thanks. I will let it rest as is. Maybe later improve the answer (after sleep,e tc). Lets stay friends please. I want to make a language where cast is never a conversion, so then we don't have this issue. Thanks for replying. I don't think it is irrelevant. The reason we have the term cast is because we need to describe the erased portion separately from the runtime portion. But anyway, I see your point too about how confusing it is. – Shelby Moore III Dec 11 '11 at 22:12
-
@MarcGravell I had the inspiration to edit the answer. Please let me know if that is a little bit better or if it still doesn't work well from your perspective. Thanks for the feedback, even if critical. I tried to incorporate your points, especially about all syntax being erased, etc. – Shelby Moore III Dec 11 '11 at 22:45
-
@quantumSoup I edited the answer. I tried to incorporate your points. What you think? Still confusing or inaccurate from your perspective? – Shelby Moore III Dec 11 '11 at 22:47
-
@JonSkeet I edited the answer. I tried to make it more clear how it relates to Eric Lippert's answer and also to the top voted answer. And to make the erased point more clear by relating it to the fact that all syntax is erased. I appreciated your feedback. Please let me know if that still doesn't work well from your perspective? I tried to also explain why I wrote the answer, what I was trying to achieve that was different than the other answers. – Shelby Moore III Dec 11 '11 at 22:49
-
@JonSkeet wrote, "Claiming that a cast is 'erased at compile-time' suggests it has no meaning". Jon all syntax is erased at compile-time. You are wrong to suggest that all syntax has no meaning. Logic fail. – Shelby Moore III Dec 11 '11 at 23:18
-
@JonSkeet wrote, "I think it would be clearer to say that a cast may or may not be translated by the compiler into code which will cause a conversion at execution time". Jon all syntax may or may not be translated into a specific form of runtime code. Your suggested definition is entirely ambiguous. – Shelby Moore III Dec 11 '11 at 23:20
-
@MarcGravell I didn't reply to your CLI point. CLI ops are the type check and potential runtime conversion. I guess you could call that a CLI cast, but it would be in the syntax of CLI. I think we generally lump all runtime together and call it either a conversion or a runtime type check and conversion. This is the reason I really prefer a language that has no runtime conversions at all. It adds so much complexity. Also the reified generics of CLI make it very challenging to implement higher-kinds. Any way, I think the meaning of cast at the language level remains correct as I have defined it. – Shelby Moore III Dec 12 '11 at 00:20
-
1That's definitely clearer, although I'm not sure it actually adds much beyond what Eric said. (I found his way of putting it easier to understand.) Note that even if a cast requires no conversion at execution time, it can still change the generated code - for example, on overload resolution. I'm not entirely sure whether that contradicts your post or not, but it may be worth mentioning. – Jon Skeet Dec 12 '11 at 07:30
-
@JonSkeet Afaics, one thing I said that Eric didn't say (yet), is that cast doesn't always cause an explicit conversion. He implied the recipe always causes an action. I bet he will clear that up when he blogs on it. Without that, it isn't clear why we need two words and need to separate the syntax from the runtime action. Agreed a cast can change other structure. We separate the semantics of cast from its implementation, although we need to know about implementation when there is conversion. That is again why I prefer a language without casting conversions. I prefer a function call instead. – Shelby Moore III Dec 12 '11 at 08:23
-
@JonSkeet I really prefer a language with no ability to throw an exception. Ideally you have a first-class union type instead. An exception destroys refactorable composition. I am sure you have run into that. Lastly I want to repeat what I said in the "expression vs. statement" answer comments. I really respect you guys. I know your knowledge about these platforms is broader than mine. My knowledge is very narrow. I couldn't possibly answer the questions you do. I looked at your answers. I never intended to come across as disrespectful. Sometimes we can't explain why things go awry. – Shelby Moore III Dec 12 '11 at 08:28
-
My main problem with this answer from the start: it seems to randomly pick and choose when to be a stickler for the terms being used, sometimes within the same sentence. The current version of the answer does this in the second sentence. – Andrew Barber Dec 12 '11 at 15:05
-
@AndrewBarber Thks for constructive feedback. Plz explain what is random in the 2nd sentence? All syntax is erased at compile-time. That is a fact, no one here disputes that. The dispute is whether "cast" is only syntax. Yet the top voted answer says that "cast" is syntax. I don't know why they dispute the top voted answer? The 2nd sentence also says that "coversion" causes some action at runtime. This is what the top voted answer says also. Also Eric Lippert's answer says this. So why are people disputing the facts of the top voted answer and Eric Lippert's answer? I really don't understand. – Shelby Moore III Dec 12 '11 at 16:37
-
@JonSkeet After reading my prior comment to AndrewBarner, can you understand why I think downvoters are illogical? It wasn't a personal attack when I said that, but rather a factual statement that they're illogical on this one. I am scratching my head trying to understand why people have such a big problem with the word "erased", now that I have explained and no one disputes that all syntax is erased and replaced with runtime. The top voted answer and Eric Lippert's answer both say that "cast" is only syntax, and that "conversion" it the action at runtime.
Is "erased" a curse word? – Shelby Moore III Dec 12 '11 at 16:42 -
You first use the rigid application of source code being erased by the compiler when talking about casting, but then you ignore it when mentioning conversion. – Andrew Barber Dec 12 '11 at 16:42
-
@AndrewBarber Thanks very much for making your point more explicit. What did I ignore about "erased" w.r.t. to "conversion"? I assume you mean that if syntax is erased, then you think it can't do any action? That would be incorrect. All syntax is erased, but that doesn't mean that the runtime does nothing. I explained in my answer what the term "erased" means. It enables us to refer to separating things that are not bijective. The source code (syntax) is not the runtime. They are different things, because runtime can't be inverted one-to-one back to syntax. – Shelby Moore III Dec 12 '11 at 16:46
-
as you note, *all syntax is erased* by the compiler. Therefore, it's essentially meaningless to say so. You seem to come close to saying what Eric said; "casting is a way to describe a type of conversion", but the distinction of "erasure" is meaningless in this context. It's implied in the very idea of compilation, in the first place. (what you write is "changed" into a more machine-friendly version). That leaves us with the run time differences... – Andrew Barber Dec 12 '11 at 16:50
-
@AndrewBarber No where did I say that the operational semantics where erased. Syntax may express some semantics. And some of the denotational semantics may be erased when syntax is. But not all of the semantics is erased, otherwise we wouldn't get a runtime. **I did not write that everything is erased.** Maybe in your mind you thought I did. You are conflating in your mind the erasure of syntax, with the erasure of everything. It is very relevant to say that syntax is erased, that is precisely what makes "cast" distinct from "conversion". My definition is very precise. – Shelby Moore III Dec 12 '11 at 16:51
-
@AndrewBarber Let take this to chat. I am opening it now and waiting for you. Thanks. I am in the C# room. Or request me to a prvt room. – Shelby Moore III Dec 12 '11 at 16:55
-
Nowhere did I say you said those things. You seem to jump to assuming people are misunderstanding you when they are simply pointing out where your logic is not making sense. – Andrew Barber Dec 12 '11 at 16:56
-
@AndrewBarber What part of my logic doesn't make sense? Or do you mean that I need to make it more clear that I am not saying that everything is erased? I am waiting for you in the C# chat room. Please go there, then we will come back here when we are done. – Shelby Moore III Dec 12 '11 at 16:57
-
Moderater please don't delete my comments. I need time to go back through these comments in the future weeks and both improve my answer and also for my own personal records of tutorials I am making outside of this site. Please I need these comments. Please. I am begging you to not delete my comments. I am not asking for anything except to let me be able to extract this information over time from this site to my personal blog. I need time to do that. I hope you understand. I won't be answering any more questions on this site. Thank you very much. – Shelby Moore III Dec 12 '11 at 17:05
-
1@Shelby If it's really important to you to save these comments, I recommend saving the page's html right now and stuffing it somewhere safe. Comments are not meant to be persistent here, as NullUserException has suggested to you before. Right or wrong, these comments are subject to being deleted, and introducing meta comments only increases that likelihood. – Andrew Barber Dec 12 '11 at 17:19
-
@AndrewBarber Done. Thank you. Note it is very difficult to save so much stuff and organize it. I prefer to use SO as my organizer for things I write here. But I am not going to try to tell you to stop deleting user's data. I tried to raise that point at Meta, and it was pounded down. – Shelby Moore III Dec 12 '11 at 17:25
-
@AndrewBarber It would be helpful if SO would let us save a snapshot copy here and keep them organized for us. – Shelby Moore III Dec 12 '11 at 17:34
-
+1 I see what you are trying to say and it helped me understanding the difference between the two :) – BlackBear Jan 17 '12 at 16:14
-
@MarcGravell wrote _“Your point about removed at compile time is [vacuous]”_. That groupthink thought so in 2011 is evidence of lacking [a coherent grasp](http://trilema.com/2018/how-to-piss-me-the-fuck-off-a-guide/) of this CompSci issue. What remains of syntax after erasure is akin to [reification](https://en.wikipedia.org/wiki/Reification_(computer_science)). Highly upvoted, incorrect conflation of syntax that is erased (e.g. ‘casts’) w\separate-concerns such as terms (e.g. ‘conversions’) that apply in the compiled model demonstrates an inability of groupthink to discriminate between models – Shelby Moore III Jun 10 '20 at 23:52
-
@ShelbyMooreIII you're essentially shaking a stick at people and saying "I'm right, and if you don't agree with me, who clearly knows better than everyone else, then you're just being a sheep"; there's no merit badges for being (hypothetically) right if you aren't *articulating* your point in a way that makes that clear to other people, and getting grumpy about it (wow, those edits, and that recent comment): doesn't improve things – Marc Gravell Jun 11 '20 at 08:47
-
@ShelbyMooreIII we're not talking about correctness; we're talking about communication skills, which is a *prerequisite* to even being able to *discuss* whether something is correct; that, as demonstrated by yet another hostile response, is where you are failing; also - I don't think "censorship" means what you think it means – Marc Gravell Jun 11 '20 at 10:28