Pages

Wednesday, 22 July 2015

Reference Conversions

Reference Conversions

As you well know by now, reference type objects comprise two parts in memory: the reference and the data.
  • 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.
For example, the following code shows two reference variables, 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 type Tt, 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 an InvalidCastException 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