C# Explicit Casting Between Types

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 = 
(Gizmo)widget1
;
(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 = 
(LibraryBookRecord)bsr
;
(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.