struct Digit
    {
        byte value;        public Digit(byte value)
        {
            if (value > 9) throw new ArgumentException();
            this.value = value;
        }        public static implicit operator byte(Digit d)
        {
            Console.WriteLine("Conversion occured");
            return (byte)((int)d.value + 1);
        }
    }    class app
    {
        static void Main()
        {
            Digit d = new Digit(5);
            byte b = d;
            Console.WriteLine(d == b);
            Console.WriteLine(d.Equlas(b));
        }
    }结果是什么呢?为什么?

解决方案 »

  1.   

    true 引用比较
    false 值比较
      

  2.   

    d==b为什么是true?光一句“引用比较”不能很全面地解释吧。d和b的运行时类型都不同,为何引用比较会相等呢?还有,为什么等号就是引用比较,Equals就是值比较?
      

  3.   

    C#和JAVA都是这样的结果的,因为在这两种语言中存在值类型和引用类型.代码中的d指向一个object,b=d之后b也指向其值也为5的一个object,也就是说b=d只是将d的值给b,而两者指向对象不同(更不用说类型不同),因此==比较时不同.而Equals是.NET中比较两个object值的方法,只是比较他们的值,不看两者引用对象是否为一个对象,因此相同.
      

  4.   

    上面说error是你的Console.WriteLine(d.Equlas(b));存在错误。单词写错了。Equals是比较引用,==是比较值,因为结构是值类型。所以==是true,Equals是false
      

  5.   

    ◎shangfeihu(摩柯罗):你实际运行过吗?结果跟你说的相反
    ◎mademelaugh(五朝臣子) 还是不对,如果是比较值,那么d是5,b是6,怎么会相等?Equals是false很好理解,关键是==运算符
      

  6.   

    说错了,Equals也可以比较值类型,但比较时会根据所比较的值的所有字段是否包含相同的值来返回true或者false。
      

  7.   

    我是这样理解的:b的值是6,d的value字段是5,这里看起来是不同,但当你执行“==”时,d会有个默认的转换,这里会使d的value字段值加一再进行比较,就成了6==6了。你可以设置一个断点看看。
      

  8.   

    另外,当Equals用于值比较时,即使相同的值,其类型不同,比较结果也是false。你可以声明一个int型和一个long型的数据,都初始化为5,用Equals比较可以看到返回false。
      

  9.   

    "但当你执行“==”时,d会有个默认的转换,这里会使d的value字段值加一再进行比较,就成了6==6了。"
    嗯,关键是这里了,那么这个转换是怎么决定的呢?为什么是从Digit转换到byte,而不是从byte转换到Digit?是不是因为只定义了从Digit到byte的隐式转换?
      

  10.   

    一般没有进行显示转换的情况下进行比较或者赋值,系统肯定只会调用隐式转换。当前并没有从byte到 Digit的转换。
      

  11.   

    我试着加上了从byte到Digit的转换,但是结果还是一样,能解释一下怎么确定进行何种转换的吗?我猜想会不会跟操作数在==号的那一边有关系?
        public static implicit operator Digit(byte b)
        {
            return new Digit(b);
        }
      

  12.   

    我想是这样了.有兴趣的可以跟综一下试试(我只是猎了.没时间试)
    d == b 是值的直接比较d.Equlas(b)执行了下面一段
            public static implicit operator byte(Digit d)
            {
                Console.WriteLine("Conversion occured");
                return (byte)((int)d.value + 1);
            }
    此时d的值为6
      

  13.   

    ◎f_lorelei(icehyp),不对,跟踪后可以发现,是在执行==运算符的时候进行的隐式转换,Equals方法根本不需要转换类型
      

  14.   

    byte b = d; //此句也应有一次隐式转换,些时b的值为6,但d本身值是不变的
    Console.WriteLine(d == b); //由于隐式转换,取到的左操作数为6,d本身值仍是不变的
    Console.WriteLine(d.Equlas(b));//Equals方法根本不需要转换类型,因此是5和6比,自然为false
      

  15.   

    ◎f_lorelei(icehyp),我的问题是执行d==b判断的时候为什么要进行隐式转换,而且为什么是从Digit到byte的转换,而不是进行byte到Digit的转换呢?
      

  16.   

    两个不同类弄比较自然会转换..这种转换是有规则的..(就像在C中int和 double比较 时会把int转成double再比)
    具体专换规则你可以找一下相关资料
      

  17.   

    Conversion occured
    Conversion occured
    True
    False
      

  18.   

    是转换==前面的d,你可以尝试把public static implicit operator byte(Digit d)声明改为
    public static explicit operator byte(Digit d)编译器会报告错误。
      

  19.   

    我知道了:因为我自己定义的Digit结构没有重载==运算符,所以当执行到==运算符的时候,必须要将==两边的操作数转换到==支持的类型。当然,byte类型肯定是支持==运算符的,而且在这里,也定义了从Digit到byte的转换,所以会执行这个转换,然后比较两个byte类型的操作数。