【问题标题】:how user define conversion happen in c# [closed]用户如何在 C# 中定义转换 [关闭]
【发布时间】:2013-02-24 09:24:21
【问题描述】:

任何人都可以解释以下程序,用户定义转换是如何显式和隐式发生的?

在显式转换方法和隐式转换方法上也请看我的cmets。

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

【问题讨论】:

  • 完全不清楚您所说的“这里是如何发生的”是什么意思。
  • @jon keet 我的意思是它如何访问值 int 构造函数??
  • 为什么不能调用构造函数?它在同一个类中声明。 (无论如何,它是一个公共构造函数。)

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


【解决方案1】:

让我们从这个例子开始:

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#中没有可以引用的名称。

【讨论】:

    【解决方案2】:
    /*** 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; // <------------------------------------------+ 
    }
    

    【讨论】:

    • 感谢 ken kin 你让它变得太容易了。
    猜你喜欢
    • 2016-04-25
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多