C# Implicit Conversions
DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
The following are my notes from section 6.1 of the C# Language Specification
Heuristic Model
- Definitions. Add definitions for the chapter.
- Examples. After adding definitions, then add examples.
- 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
anddynamic
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
anddynamic
- class-type
S
++++> class-typeT
providedS
derives fromT
- class-type
S
++++> interface-typeT
providedS
implementsT
- interface-type
S
++++> interface-typeT
providedS
derives fromT
- array-type
S
with element typeSE
++++> array-typeT
with element typeTE
providedS
andT
differ only in element type (e.g. same number of dimensions)- Both
SE
andTE
are reference-types - An implicit conversion exists from
SE
toTE
- 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 fromS
toT
- delegate-type ++++>
System.Delegate
and the interfaces it implements - null ++++> any reference-type
- any reference-type
S
++++>T
providedS
has an implicit identity conversion toU
andU
has an identity conversion toT
- any reference-type
S
to interface- or delegate-typeT
providedS
has an implicit identity or reference conversion to an interface- or delegate-typeU
andU
is variance-convertible toT
- 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
- any reference type ++++>
- 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
- if
- non-nullable-value-type
S
++++>object
|dynamic
|System.Valuetype
| any interface-type implemented byS
- enum-type ++++>
System.Enum
- nullable-value-type
S
++++> reference-typeT
provided a boxing conversion exists for the non-nullable-value-type - value-type
T
++++> interface-typeI
providedT
has a boxing conversion toJ
andJ
has an identity conversion toI
- value-type
T
++++> interface-typeI
providedT
has a boxing conversion to an interface- or delegate-typeJ
andJ
is variance-convertible toI
- struct ++++>
System.ValueType
- comments:
- implicit dynamic conversions
dynamic
++++> any typeT
- 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
toobject
- 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
inT
's effective interface set - any base interface of
I
- ---
- a type parameter
U
providedT
depends onU
- ---
- a reference type of
R
provided - it has an implicit conversion to a reference type
S
and S
has an identity conversion toR
- an interface type
I
provided - it has an implicit conversion to an interface or delegate type
J
and J
is variance-convertible toI
null
literal ++++>T
providedT
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