Search code examples
c#castingoperatorsimplicit-conversionexplicit-conversion

how user define conversion happen in c#


Can any one explain the following program that how user define conversion happen both explicitly and implicitly?

Please also see my comments at the explicitly conversion method and implicit conversion method.

/*** conversion.cs ***/

using System;
using System;

struct RomanNumeral {
    public RomanNumeral(int value) {
        this.value=value; // what happen here?? 
    }

    static public implicit operator RomanNumeral(int value) {
        // here the default constructor is called  and the parameter in the 
        // argument is passed for the conversion to RomanNumeral but the 
        // constructor is of the type int so how it happen please explain?? 
        return new RomanNumeral(value); 
    }

    static public explicit operator int(RomanNumeral roman) {
        return roman.value;//how it is  happen here??
    }

    static public implicit operator string(RomanNumeral roman) {
        return ("Conversion not yet implemented");
    }

    private int value;
}

class Test {
    static public void Main() {
        RomanNumeral numeral;

        numeral=10;


        Console.WriteLine((int)numeral);


        Console.WriteLine(numeral);


        short s=(short)numeral;

        Console.WriteLine(s);
    }
}

Solution

  • /*** Answer with the comments in code ***/
    // You can imagine that conversion operator as `cast constructor`, though 
    // it can output an instance of target type in the ways other than a real 
    // constructor. 
    // The semantic model is `OutputType(InputType value)`
    // which means the LHS is of `OutputType` and RHS is of `InputType`. 
    // For more information, see 
    //      http://msdn.microsoft.com/en-us/library/85w54y0a.aspx
    struct RomanNumeral {
        public RomanNumeral(int value) {
            // here the parameter `value` assiged to the field value ----+
            this.value=value;                                         // |
        }                                                             // |
        //                                                               |
        static public implicit operator RomanNumeral(int value) {     // |
            // RomanNumeral(int value) is semantically tells that it     |
            // outputs a `RomanNumeral` from taking an `int` like        |
            // the constructor.                                          |
            // Thus if there was a method `M(RomanNumeral x)`            |
            // and called with M(3), then it's called with               |
            // M((RomanNumeral)3) by effection of this implicit operator |
            // and because it's implicit, you don't need to explicitly   |
            // cast it.                                                  |
            return new RomanNumeral(value);                           // |
        }                                                             // |
        //                                                               |
        static public explicit operator int(RomanNumeral roman) {     // |
            // Here the explicit operator just does the reverse thing    |
            // of what the implicit operator does                        |
            // However, because it's declared as explicit, you'll need   |
            // to tell the compiler you want to cast explicitly, or the  |
            // compiler treats statement like `int x=myRoman;` as an     |
            // error where `myRoman` is assumed a `RomanNumeral`         |
            // So you would write the statement as `int x=(int)myRoman;` |
            // and it compiles.                                          |
            return roman.value;                                       // |
        }                                                             // |
        //                                                               |
        static public implicit operator string(RomanNumeral roman) {  // |
            return ("Conversion not yet implemented");                // |
        }                                                             // |
        //                                                               |
        private int value; // <------------------------------------------+ 
    }