| 1. | .Net allows you to cast between primitives without defining explicit
cast methods, e.g.
float f = 1.23F;
int i = (int)f;
It also allows you to cast derived classes into an ancestor classes and vice versa, e.g.
Uri uri = new Uri("http://www.thing.com");
Object obj = (Object)uri;
Uri uri2 = (Uri)obj;
But for user defined or complex classes, no explicit casting method is available and without you
defining exactly how the conversion would work, the cast fails:
Widget widget1 = new Widget();
Gizmo gizmo1 =
(local variable) Widget widget1
Error: Cannot convert type 'Widget' to 'Widget.Gizmo' |
| 2. | As an example, let us define two similar classes, one for Books sold in a bookshop,
and one for Books being stored in a Library. They both contain 4 data items, only two of which are the same between them.
The numeric fields are made nullable. Each defines a standard constructor with the 4 items, and an empty constructor.
public class BookSaleRecord
{
public string Title;
public string Author;
public int? YearofPublication;
public decimal? price;
public BookSaleRecord() { }
public BookSaleRecord(string title, string author, int yearpublished, decimal price)
{
this.Author = author;
this.Title = title;
this.price = price;
this.YearofPublication = yearpublished;
}
}
public class LibraryBookRecord
{
public string BookTitle;
public string Writer;
public int? YearPurchased;
public int? BorrowFreq;
public LibraryBookRecord() { }
public LibraryBookRecord(string booktitle, string writer, int yearbought, int frequency)
{
this.Writer = writer;
this.BookTitle = booktitle;
this.BorrowFreq = frequency;
this.YearPurchased = yearbought;
}
}
|
| 3. | As above, we cannot cast from one to the other implicitly:
BookSaleRecord bsr = new BookSaleRecord("The Pickwick Papers", "Charles Dickens", 1836, 1.99M);
LibraryBookRecord lbr =
(local variable) BookSaleRecord bsr
Error: Cannot convert type 'BookSaleRecord' to 'BookSaleRecord.LibraryBookRecord' |
| 4. | But we can add the explicit conversion to the LibraryBookRecord object, using the explicit operator keyword, to generate a new target object and copy over the appropriate values into the new object before returning it as the result of the cast:
public static explicit operator LibraryBookRecord(BookSaleRecord b)
{
LibraryBookRecord newLib = new LibraryBookRecord();
newLib.BookTitle = b.Title;
newLib.Writer = b.Author;
newLib.YearPurchased = null;
newLib.BorrowFreq = null;
return newLib;
}
Note that we have to add the conversion code to the object we wish to convert TO. If we wanted to convert back the way, then we need to add a similar mapping
method to the BookSaleRecord object. Any properties of the new class we don't know, we can set to null. This allows us to cast between them:
BookSaleRecord bsr = new BookSaleRecord("The Pickwick Papers", "Charles Dickens", 1836, 1.99M);
Console.WriteLine("Bookshop Book Title: " + bsr.Title);
LibraryBookRecord lbr = (LibraryBookRecord)bsr;
Console.WriteLine("Library Book Title: " + lbr.BookTitle);
output:Bookshop Book Title: The Pickwick Papers Library Book Title: The Pickwick Papers |
| And that is all there is to Explicit casting. By including a custom explicit operator, you can define the mapping between objects and then use simple casting in your program. | |