Friday 17 March 2017

More on Explicit and Implicit conversions

There's something that I should add regarding my previous post about implicit conversions. As implicit conversions are managed by the compiler that inserts a call to the static method where you have defined the implicit conversion in your class, it will only work when the type of the variable referencing to your object is right that type, not a base one. I mean, for the example of the other day, where our Person class had defined an implicit conversion to String, the last line will not compile:

var p1 = new Person("Xuan");
string name = p1;
Console.WriteLine(name);

Console.WriteLine(DoFormat(p1));

Object o1 = p1;
//this line does not compile, "Cannot implicitly convert type 'object' to 'string'
//name = o1;

For explicit conversions, we'll get the problem at runtime. Let's say that we write this code:

 public class Animal
 {
  public string Name {get;set;}
  
  public Animal(string name)
  {
   this.Name = name;
  }
  
  public static explicit operator String(Animal a)
  {
      return a.Name;
  }
 }
 
 public static void Main(string[] args)
  {
   Console.WriteLine("started");
   
   var a1 = new Animal("ABC");
   string name = (string) a1;
   Console.WriteLine(name);

   Object o1 = a1;
   //this line crashes at runtime
   //we have an Object variable, not an Animal, so it will not set a call to the Conversion operator, but a call to a real cast, that will fail at runtime. 
   name = (string) o1;
   
   //the line below does not compile
   //"as" operator does not work for explicit conversions, it's only the cast operator
   //name = a1 as String;

  }
 }

For explicit conversions we use the cast operator, that as we know can mean 2 very different things, a "type hint" or a conversion. In this case the compiler sees that the Object class does not define any explicit conversion to string, so will assume that this cast means a "type hint" here, so it will translate it into a castclass IL instruction. At execution time the cast will fail and we'll get an exception:
System.InvalidCastException: Unable to cast object of type 'ExplicitConversions.Animal' to type 'System.String'

One additional point to note regarding explicit conversions, the as operator can not be used for invoking user defined explicit conversions. So this is one more point where it differs from the cast operator.

No comments:

Post a Comment