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
- 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
- requires an explicit cast
- occur only for expressions of type dynamic
- from any type to the same type
-
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
- 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
- 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?
- null literal to any nullable type
- the result is the null value of the given type
-
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
provided-
S
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
-
T
++++>
System.Array
and the interface it implements
S[]
++++>
IList<T>
and its base interfaces provided there is an implicit identity OR reference conversion from
S
to
T
System.Delegate
and the interfaces it implements
S
++++>
T
provided
-
S
has an implicit identity conversion toU
and -
U
has an identity conversion toT
S
to interface- or delegate-type
T
provided
-
S
has an implicit identity or reference conversion to an interface- or delegate-typeU
and -
U
is variance-convertible toT
- 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
-
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
S
++++>
object
|
dynamic
|
System.Valuetype
| any interface-type implemented by
S
System.Enum
S
++++> reference-type
T
provided a boxing conversion exists for the non-nullable-value-type
T
++++> interface-type
I
provided
-
T
has a boxing conversion toJ
and -
J
has an identity conversion toI
T
++++> interface-type
I
provided
-
T
has a boxing conversion to an interface- or delegate-typeJ
and -
J
is variance-convertible toI
System.ValueType
-
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
- the binding of the operation is suspended until run-time
-
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
-
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
- consists of three parts
- optional standard implicit conversion
- user-defined implicit conversion operator
- optional standard implicit conversion
- these do not have types in and of themselves
- may be implicitly converted to delegate types OR expression-tree types
- "Some conversions are defined by the language. Programs may also define their own conversions." (introduction)