用户如何在c#中定义转换

时间:2013-03-08 18:19:32

标签: c# casting operators implicit-conversion explicit-conversion

任何人都可以解释以下程序,用户如何明确地和隐含地定义转换?

还请在显式转换方法和隐式转换方法中查看我的评论。

/*** 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);
    }
}

2 个答案:

答案 0 :(得分:2)

让我们看看这个例子开头:

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

为了便于阅读,我已移动并重新格式化了您的评论。

首先,不,默认构造函数被调用(直接,无论如何)。调用RomanNumeral(int)构造函数。

将隐式运算符视为自动调用的方法很有用。所以想象我们有一个这样的静态方法:

// Note: body is the same as the implicit conversion
public static RomanNumeral FromInt32(int value)
{
    return new RomanNumeral(int value);
}

然后你可以想到这个:

int x = 10;
RomanNumeral numeral = x;

编译为:

int x = 10;
RomanNumeral numeral = RomanNumeral.FromInt32(x);

只是操作员在C#中没有名称的方法。

答案 1 :(得分:0)

/*** 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; // <------------------------------------------+ 
}