#1,076 – Implicit Numeric Conversions from the char Type

You can implicitly convert an instance of a char to any of the following numeric types:

ushort int, uint, longulong, float, double, or decimal

When you implicitly convert a char to a numeric value, you use the associated code point as the numeric value.  Because of this implicit conversion, you can use char instances within numeric expressions.  Below are some examples:

            int n = 'a';  // 97
            char c1 = 'a';
            n = c1;  // still 97

            char c2 = '\u1820';
            int n2 = c2;  // 6176 (0x1820)

            int delta = 'd' - 'a';  // 3
            int strangeSum = 'a' + 'b';  // 97 + 98 = 195

#1,060 – Explicit Conversions between Nullable Types

An implicit conversion exists between two nullable types if an implicit conversion exists between the corresponding value types.  For example:

int i = 12;
long l = i;  // implicit int to long
int? i2 = 12;
long? l2 = i2;  // implicit int? to long?

Similarly, an explicit conversion exists between two nullable types if an explicit conversion exists between the corresponding value types.

long l = 12;
int i = (int)l;  // explicit long to int
long? l2 = 12;
int? i2 = (int?)l2;  // explicit long? to int?

You can also convert between a nullable and non-nullable type, either implicitly or explicitly.  An explicit conversion is required when converting from a nullable type to a non-nullable type or when an explicit conversion is required by the underlying types.

            int? i3 = (int?)l;   // explicit long to int?
            long l3 = (long)i3;  // explicit int? to long

#1,055 – Defining Your Own Implicit Conversions

Suppose that you define a new value type, for example the TimedInteger type shown below.

    public struct TimedInteger
        private int theInt;
        private DateTime whenCreated;

        public TimedInteger(int value)
            theInt = value;
            whenCreated = DateTime.Now;

You can now create instances of this type as follows:

            TimedInteger ti = new TimedInteger(5);

You can’t directly assign an integer to a variable of type TimedInteger because no implicit conversion exists between an integer literal and your type.  (Between an int and your type).

To allow this assignment, you can define a custom implicit conversion for your type.  The code below allows an implicit conversion from an int to a TimedInteger.

        public static implicit operator TimedInteger(int value)
            return new TimedInteger(value);

You can now directly assign an integer literal, because there is an implicit conversion between int and TimedInteger.

            TimedInteger ti = 5;


#1,047 – The Implicit Identity Conversion

One of the implicit conversions that exists in C# is the identity conversion, which states that an expression of a given type can be implicitly converted to that same type.

This sounds silly and unnecessary, but allows the compiler to know that assignments like the one below are allowed.

            int anInt = 12;

            // Identify conversion allows the
            // following assignment as an
            // implicit conversion
            int another = anInt;

#566 – Implicit Conversions to Nullable Types

A nullable type represents a type whose value can be either a particular value type or can be the null value.

int i = 12;   // regular int, can't be null

int? j = 22;  // Nullable int, can store an int value
j = null;     // Can also store null value

You can implicitly convert from the corresponding value type to its matching nullable type.  For example, you can convert from an object of type int to an object of type int?

int i = 12;
int? j = i;   // Implicit conversion from int to int?

float f1 = i;   // Implicit conversion from int to float
float? f2 = i;  // Implicit conversion from int -> float -> float?

You can also implicitly convert from the null value to any nullable type.

int? i = null;