This article was previously published under Q304696
This article has been archived. It is offered "as is" and will no longer be updated.
When you compile your code, you receive the following compiler error message:
Cannot implicitly convert type <type> to <type>
Conversions must occur when you assign a variable of one type to a variable of a different type. When you make an assignment between variables of different types, the compiler must convert the type on the right side of the assignment operator to the type on the left side of the assignment operator. For example, consider the following the code:
int i = 50;long lng = 100;i = lng;
Notice that the last statement is making an assignment, but the data types of the variables on the left and right sides of the assignment operator don't match. Before making the assignment, the compiler is implicitly converting the variable "lng", which is of type long, to type int. This is called implicit because the code does not explicitly tell the compiler to perform this conversion. The compiler is doing it automatically. The problem with this code is that this is considered a "narrowing" conversion, and implicit narrowing conversions are not allowed by the compiler. They are not allowed because a loss of data may result.
Narrowing vs. Widening Conversions
Let's take a moment to define what we mean by narrowing and widening conversions and why there is a potential loss of data.
A narrowing conversion exists when you convert a data type to another data type that occupies less storage space in memory. For example, converting a long to an int would be considered a narrowing conversion. A long occupies 8 bytes of memory while an int occupies 4 bytes of memory. The code provided earlier is an example of a narrowing conversion. How could data loss occur in this situation? For example, consider the following code:
int i = 50;long lng = 3147483647;i = lng;
Notice that compared to the previous sample, the value being assigned to our long data type is changed. The variable lng now contains a value that cannot be stored in the variable i because it is too large. If you were to convert this value to an int type, you would lose some data and the converted value would not be the same as the value before the conversion. The compiler error is a way of warning you of that loss.
A widening conversion would be the opposite of a narrowing conversion. With widening conversions, you are converting to a data type that occupies more storage space in memory than the data type that you are converting from. Here is an example of a widening conversion:
int i = 50;long lng = 100;lng = i;
Notice the difference between this code sample and the first. This time the variable lng is on the left side of the assignment operator, so it is the target of our assignment. Before the assignment can be made the compiler must implicitly convert the variable i, which is of type int, to type long. This is a widening conversion because we are converting from a type that occupies 4 bytes of memory (an int) to a type that occupies 8 bytes of memory (a long). Implicit widening conversions are allowed because there is no potential loss of data. Any value that can be stored in an int can also be stored in a long.
Implicit narrowing conversions are not allowed, so to be able to compile this code you must explicitly convert the data type. Explicit conversions are done by using casting. Casting is the term used in C# to describe converting one data type to another. To get the code to compile, you would need to use the following syntax:
int i = 50;long lng = 3147483647;i = (int) lng;
Notice that this precedes the right operand with a type name in parenthesis. This is so that the compiler knows that you want an explicit conversion to this type. This code sample is telling the compiler to explicitly convert the variable lng, which is of type long, to an int before making the assignment. We say that we are casting the variable lng to an int. Although this is allowed, you should note that with narrowing conversions there is a potential loss of data and they should be used with caution. Even though the code will compile, you may get unexpected results at run time.
This behavior is by design.
In this article we have been working only with value types. When working with value types you work directly with the data stored in the variable. However, C# .NET has two types, value and reference. When working with reference types, you are working with a reference to a variable, not the actual data. Examples of reference types would be classes, interfaces, and arrays. You cannot implicitly or explicitly convert one reference type to another. Such types of conversions can be done by using the System.Convert class.