Reference Conversions
As you well know by now, reference type objects comprise two parts in memory: the reference and the data.
A delegate can be implicitly converted to the .NET BCL classes and interfaces shown in following figure.
An array,
Explicit conversions include conversions from an object to any reference type and conversions from a base class to a class derived from it.
This type of conversion were allowed without restriction, you could easily attempt to reference members of a class that are not actually in memory. The compiler, however, does allow these types of conversions. But when the system encounters them at run time, it raises an exception.
For example:
The first case is where the explicit conversion is unnecessary—that is, where the language would have performed an implicit conversion for you anyway. For example, in the following code, the explicit conversion is unnecessary because there is always an implicit conversion from a derived class to one of its base classes.
The second case is where the source reference is
The third case is where the actual data pointed to by the source reference could safely be converted implicitly. The following code shows an example.
- Part of the information held by the reference is the type of the data it is pointing at.
- A reference conversion takes a source reference and returns a reference pointing at the same place in the heap but “labels” the reference as a different type.
myVar1
and myVar2
, that point to the same object in memory.
class A { public int Field1; } class B: A { public int Field2; } class Program { static void Main( ) { B myVar1 = new B(); A myVar2 = (A) myVar1; Console.WriteLine(myVar2.Field1); // Fine Console.WriteLine(myVar2.Field2); // Compile error! } }
Implicit Reference Conversions
Just as there are implicit numeric conversions that the language will automatically perform for you, there are also implicit reference conversions.- All reference types have an implicit conversion to type object.
- Any interface can be implicitly converted to an interface from which it is derived.
- A class can be implicitly converted to any class in the chain from which it is derived or any interface that it implements.
A delegate can be implicitly converted to the .NET BCL classes and interfaces shown in following figure.
An array,
ArrayS
, with elements of type Ts
, can be implicitly converted to the following:
- The .NET BCL class and interfaces.
- Another array,
ArrayT
, with elements of typeTt
, if all of the following are true:- Both arrays have the same number of dimensions.
- The element types, Ts and Tt, are reference types—not value types.
- There is an implicit conversion between types Ts and Tt.
Explicit Reference Conversions
Explicit reference conversions are reference conversions from a general type to a more specialized type.Explicit conversions include conversions from an object to any reference type and conversions from a base class to a class derived from it.
This type of conversion were allowed without restriction, you could easily attempt to reference members of a class that are not actually in memory. The compiler, however, does allow these types of conversions. But when the system encounters them at run time, it raises an exception.
For example:
class A { public int Field1; } class B: A { public int Field2; } class Program { static void Main( ) { B myVar1 = new B(); A myVar2 = (A) myVar1; //unsafe - could raise an exception } }
Valid Explicit Reference Conversions
There are three situations in which an explicit reference conversion will succeed at run time—that is, not raise anInvalidCastException
exception.
The first case is where the explicit conversion is unnecessary—that is, where the language would have performed an implicit conversion for you anyway. For example, in the following code, the explicit conversion is unnecessary because there is always an implicit conversion from a derived class to one of its base classes.
class A { } class B: A { } ... B myVar1 = new B(); A myVar2 = (A) myVar1; // Cast is unnecessary; A is the base class of B.
The second case is where the source reference is
null
. For example, in the following code, eventhough it would normally be unsafe to convert a reference
of a base class to that of a derived class, the conversion is allowed because the value of the source reference is null
.
class A { } class B: A { } ... A myVar1 = null; B myVar2 = (B) myVar1; // Allowed because myVar1 is null
The third case is where the actual data pointed to by the source reference could safely be converted implicitly. The following code shows an example.
class A { } class B: A { } ... B myVar1 = new B(); A myVar2 = myVar1; // Implicitly cast myVar1 to type A. B myVar3 = (B)myVar2; // This cast is fine because the data is of type B.
0 comments:
Post a Comment