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. |