Welcome to Shaun Luttin's public notebook. It contains rough, practical notes. The guiding idea is that, despite what marketing tells us, there are no experts at anything. Sharing our half-baked ideas helps everyone. We're all just muddling thru. Find out more about our work at bigfont.ca.

C# Implicit Conversions

Tags: C#, csharp-language-specification

DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT

The following are my notes from section 6.1 of the C# Language Specification

Heuristic Model

  1. Definitions. Add definitions for the chapter.
  2. Examples. After adding definitions, then add examples.
  3. Edit. After adding examples, then edit for readability etc.

My Personal Conventions

  • ++++> means "converts to"
  • section headers are underlined and bold
  • terminology is italicized
  • everything is presented in the order that it occurred in the section

Terminology in Order of First Occurrence

  • conversion
    • lets us treat an expression as a specific type
    • either convert a typed expression to another type, or
    • give a type to an un-typed expression
  • expression
  • type
  • implicit conversion
    • can be pre-defined or user-defined
    • can occur in a variety of circumstances
    • should always succeed and never throw exceptions
    • types object and dynamic are considered equal for the purposes of conversion
  • explicit conversion
    • requires an explicit cast
  • dynamic conversions
    • occur only for expressions of type dynamic
  • implicit identity conversion
    • from any type to the same type
  • constructed type
  • implicit numeric conversion
    • sbyte
    • byte
    • short
    • ushort
    • int
    • uint
    • long
    • ulong
    • char
    • float
    • may cause loss of precision but never loss of magnitude
    • never lose any information
    • no implicit conversions to the char type
  • implicit enumeration conversions
    • decimal-integer-literal 0 converts to any enum-type and to any nullable types whose underlying  type is an enum-type
    • the latter converts to underlying type and then wraps the result
  • underlying type
  • wrapping
  • implicit nullable conversion
    • if there is an implicit conversion for a predefined non-nullable value type,
    • then there is also an implicit conversion for its nullable equivalent
    • S ++++> T?
    • S? ++++> T?
  • unwrapping
  • implicit null literal conversions
    • null literal to any nullable type
    • the result is the null value of the given type
  • implicit reference conversions
    • any reference type ++++> object and dynamic
    • class-type S ++++> class-type T provided S derives from T
    • class-type S ++++> interface-type T provided S implements T
    • interface-type S ++++> interface-type T provided S derives from T
    • array-type S with element type SE ++++> array-type T with element type TE provided
      • S and T differ only in element type (e.g. same number of dimensions)
      • Both SE and TE are reference-types
      • An implicit conversion exists from SE to TE
    • array-type T ++++> System.Array and the interface it implements
    • array-type S[] ++++> IList<T> and its base interfaces provided there is an implicit identity OR reference conversion from S to T
    • delegate-type ++++> System.Delegate and the interfaces it implements
    • null ++++> any reference-type
    • any reference-type S ++++> T provided
      • S has an implicit identity conversion to U and
      • U has an identity conversion to T
    • any reference-type S to interface- or delegate-type T provided
      • S has an implicit identity or reference conversion to an interface- or delegate-type U and
      • U is variance-convertible to T
    • implicit conversions involving type parameters that are known to be reference-types
    • comments:
      • require no checks at run-time because the compiler can prove they will always succeed
      • never change the referential identity of the converted object, i.e.
      • a reference conversion changes the type of the reference NOT the value nor type of the referred to object
  • variance convertible
    •  
  • implicit boxing conversions
    • comments:
      • convert a value-type into a reference-type
      • process for non-nullable-value-types:
        • allocate an object instance,
        • then copy the value-type value into that instance
      • process for nullable-value-types:
        • if HasValue is false, then create a null reference-type
        • otherwise, unwrap and convert the source value as normal
    • non-nullable-value-type S ++++> object | dynamic | System.Valuetype | any interface-type implemented by S
    • enum-type ++++> System.Enum
    • nullable-value-type S ++++> reference-type T provided a boxing conversion exists for the non-nullable-value-type
    • value-type T ++++> interface-type I provided
      • T has a boxing conversion to J and
      • J has an identity conversion to I
    • value-type T ++++> interface-type I provided
      • T has a boxing conversion to an interface- or delegate-type J and
      • J is variance-convertible to I
    • struct ++++> System.ValueType
  • implicit dynamic conversions
    • dynamic ++++> any type T
    • it's dynamically bound: the conversion is sought at run-time to the run-time type T
    • if no conversion is found, a run-time exception will be thrown
    • it is the seeking of the conversion, not the conversion itself, that throws the exception
    • we can avoid dynamic binding by first converting dynamic to object
  • dynamic binding
    • the binding of the operation is suspended until run-time
  • implicit constant expression conversions
    • int ++++>
      • sbyte, byte, short, ushort, uint, ulong
      • provided that the constant-expression is within the range of the destination type
    • long ++++> ulong provided that the value of the constant-expression is not negative
  • constant expression
  • implicit conversions involving type parameters
    • if T is a type paramenter, then
    • T ++++>
      • its effective base class C
      • any base class of C
      • any interface that C implements
      • ---
      • any interface I in T's effective interface set
      • any base interface of I
      • ---
      • a type parameter U provided T depends on U
      • ---
      • a reference type of R  provided
        • it has an implicit conversion to a reference type S and
        • S has an identity conversion to R
      • an interface type I provided
        • it has an implicit conversion to an interface or delegate type J and
        • J is variance-convertible to I
    • null literal ++++> T provided T is a reference type
    • comments:
      • if T is a known reference type, these are all implicit reference conversions
      • else, they are boxing conversions
  • dependent type
  • user-defined implicit conversions
    • consists of three parts
    • optional standard implicit conversion
    • user-defined implicit conversion operator
    • optional standard implicit conversion
  • anonymous function conversions and method group conversions
    • these do not have types in and of themselves
    • may be implicitly converted to delegate types OR expression-tree types
  • user-defined
    • "Some conversions are defined by the language. Programs may also define their own conversions." (introduction)
  • predefined