Saturday, January 12, 2013

Implicit Conversions in C#.NET


Conversions do one thing and one thing alone—allow an expression of one type to be treated as another type. Conversions can take one of two forms:

Implicit. These are conversions that can occur automatically as required within the code.
Explicit. These conversions require a cast to be called.

In this post we will be discussing about implicit conversions.

All conversions in C# must be static and must either take the type that the conversion is defined on or return that type.

int x = 01234;
long y = x; // this is an implicit conversion, from int to long
int z = (int) y; // this is an explicit conversion, from long to int

In the preceding example, there is a conversion from int to long. This is an implicit conversion, and expressions of the type int can be treated as though they have the type long. However, the reverse, a conversion from long to int, is an explicit conversion, and an explicit cast is needed for this to work.

Implicit Conversions

The following conversions are all considered implicit:

❑ Identity conversions
❑ Implicit numeric conversions
❑ Implicit enumeration conversions
❑ Implicit reference conversions
❑ Boxing conversions
❑ Implicit type parameter conversions
❑ Implicit constant expression conversions
❑ User-defined implicit conversions

There are many situations where an implicit conversion can occur. For example, in:

❑ Assignments
❑ Function member invocations
❑ Cast expressions

Identity Conversions

An identity conversion involves a conversion from one type to the same type. Very little is useful about this. It serves as nothing more than a way of making sure that errors aren’t generated when trying to convert one type to the same type.

Implicit Numeric Conversions

The following are implicit numeric conversions:

❑ From sbyte to decimal, double, float, int, long, and short
❑ From long to double, decimal, or float
❑ From ulong to double, decimal, or float
❑ From char to double, decimal, float, ushort, int, uint, long, or ulong
❑ From float to double
❑ From byte to decimal, double, short, ushort, int, uint, long, ulong, or float
❑ From short to double, decimal, int, long, or float
❑ From ushort to double, decimal, int, uint, long, ulong, or float
❑ From int to double, decimal, long, or float
❑ From uint to double, decimal, long, ulong, or float

Conversions from int, uint, long or ulong to float and from long or ulong to double quite often cause a loss of precision in the resulting value. This should be borne in mind if you’re carrying out highprecision

technical work. However, such conversions will never cause a loss of magnitude of the value (a number that has a magnitude that is 103 will still retain the same magnitude). 

No other implicit numeric conversions cause any loss of precision in the resulting value.

It’s important to bear in mind that no implicit conversion to the char type is possible, and other integral values won’t automatically convert to this type (if you think about it, it wouldn’t make sense if they did, since character strings would make no sense as any other type).

Implicit Enumeration Conversions

Implicit enumeration conversions simply allow the decimal integer literal 0 to be converted to any enum type without causing an error. The enum types are:

❑ byte
❑ sbyte
❑ short
❑ ushort
❑ int
❑ uint
❑ long
❑ ulong

Implicit Reference Conversions

The following are implicit reference conversions:

❑ From any reference type to object
❑ From any class type S to any class type T, provided S is derived from T
❑ From any class type S to any interface type T, provided S implements T
❑ From any interface type S to any interface type T, provided S is derived from T
❑ From any array type to System.Array
❑ From any delegate type to System.Delegate
❑ From any array type to any interface implemented by System.Array
❑ From any delegate type to System.ICloneable
❑ From the null type to any reference type
❑ From an array type S with an element type SE to an array type T with an element type TE, provided all of the following are true:
       ❑ S and T differ only in element type.
       ❑ An implicit reference conversion exists from SE to TE.
❑ From a one-dimensional array type S[] to System.Collections.Generic.IList<S> and base interfaces of this interface

❑ From a one-dimensional array type S[] to System.Collections.Generic.IList<T> and base interfaces of this interface (if there is an implicit reference conversion from S to T)

If the type parameter is known to be a reference type, the following implicit references exist:

❑ From the null type to T
❑ From T to its effective base class C, from T to any base class of C, and from T to any interface implemented by C

❑ From T to an interface type I in T’s effective interface set and from T to any base interface of I
❑ From T to a type parameter U, provided that T depends on U

Boxing Conversions

A boxing conversion allows any value type to be implicitly converted as follows:

❑ To the type object
❑ To System.ValueType
❑ To any interface type implemented by the value type

It also allows any enum type to be implicitly converted to System.Enum.

Boxing a value of a value type consists of:

❑ Allocating an object instance
❑ Copying the value type value into that instance A few additional notes:
❑ An enum can be boxed to the type System.Enum, because it is the direct base class for all enums.
❑ A struct or enum can be boxed to the type System.ValueType, because that is the direct base class for all structs and a base class for all enums.

For any type parameter T that is not a reference type, the following are all considered to be boxing conversions:

❑ From T to its effective base class C, from T to any base class C, and from T to any interface implemented by C
❑ From T to an interface type I in T’s interface set and from T to any base interface of I

Implicit Type Parameter Conversions

For a type parameter T that is not known to be a reference type, there will be an implicit conversion   from T to a type parameter U, provided that the type parameter T depends on U.

At runtime, if T is a value type and U is a reference type, the conversion will be carried out as though it is a boxing conversion.

At runtime, if both T and U are value types, T and U are necessarily the same type, and no conversion will be carried out on either of the types. At runtime, if T is a reference type, U will also be a reference type, and the conversion is carried out as either an implicit reference conversion or an identity conversion.

Implicit Constant Expression Conversions

An implicit conversion expression allows for the following conversions to be carried out:

❑ Any constant expression of the type int can be converted to byte, sbyte, short, ushort, uint, or ulong as long as the value of the constant expression is within the range of the resulting type.
❑ Any constant expression of the type long can be converted to the type ulong, as long as the value of the constant expression is not negative.

User Defined Implicit Conversions

A user-defined implicit conversion consists of:

❑ An optional standard implicit conversion, followed by
❑ The execution of a user-defined implicit conversion operator, followed by
❑ Another optional standard implicit conversion

No comments:
Write comments
Recommended Posts × +