大家好,看到一个人说引用型对象最好用 .Equals() 来判断,而值型则用 ==。作者说这个原则也应该扩展到自己所编写的代码中。
请问为什么会有这种区别?就我所知,值类型如果用 .Equals(object obj) 来判断,会涉及装箱及拆箱。并没有听说还有其它的讲究。请大家帮忙分析一下。谢谢!

解决方案 »

  1.   

    Equals是判断两个对象的值是否相等,ReferenceEquals才是判断是否为同一个引用对象
    ==如果是用于引用类型则是判断是否为同一个引用对象因此我估计你所说的“引用型对象最好用 .Equals() 来判断,而值型则用 ==”是为了用于判断值相等
    其实根本就没有 最好用什么,主要是看你要用来干什么
      

  2.   

    C#中
    ==是用来判断变量的值是否相等 相等返回true 不相等返回false。Equals是用来判断两个对象(除string类型外)是否相等,相等的条件是:值,地址,引用全相等),因为String类重写了Equals方法,所以当string类型的对象用Equals方法比较时只比较两个对象有值 相等返回true 不相等返回false。在字符串比较中,尽量使用Equals因为其平均效率要高于其他的比较方法,特别高于compare。因为Equals会先比较散列码,其速度是compare100倍以上,不包含内置对象的比较也要稍微快点。  
      

  3.   

    ref:http://blog.csdn.net/Knight94/archive/2006/08/11/1050901.aspx
      

  4.   

    dotNet中不建议使用equals(),而使用== 因为dotNet支持运算符重载的,两个方法实际是一样的.你说的比较引用和比较值,并区别开是在java中要注意的.dotNet不用关心这个,你在用==比较引用类型时候会自动进行比较.
      

  5.   

    sqllong 给的网址:http://blog.csdn.net/Knight94/archive/2006/08/11/1050901.aspx
    这篇文章上说的最后一句话:“最后一点,值类型最好不要重载定义Equals函数,而引用类型最好不要重载定义==操作符。”就是我不明白的!文章说 == 和 != 不适用于引用类型。为什么?我写了一个类,其中既重载了 Equals 也重载了 ==。大家看看,这个类有问题吗?我就是搞不明白为什么会有上面的讲究。
    using System;
    using System.Collections.Generic;
    using System.Text;namespace XFCS.Core
    {
        /// <summary>
        /// 价格。
        /// </summary>
        public class Price
        {
            #region Constructors        static Price()
            {
                maxInput = GetEffectivePrice((decimal.MaxValue - (decimal)0.5) / 100);
            }        /// <summary>
            /// 以指定的价格值初始化。
            /// </summary>
            /// <param name="priceValue">价格值</param>
            /// <res>priceValue 不能小于零或大于 <code>Price.MaxInput</code>所指定的值。</res>
            /// <exception cref="System.ArgumentException"></exception>
            public Price(decimal priceValue)
            {
                if (priceValue < 0) throw new ArgumentException("Price can't be negative");
                if (GetEffectivePrice(priceValue) > maxInput) throw new ArgumentException("Price value is too big");            this.priceValue = GetEffectivePrice(priceValue);
            }        /// <summary>
            /// 以指定的价格值初始化。
            /// </summary>
            /// <param name="priceValue">价格值</param>
            /// <res>priceValue 不能小于零或大于 <code>Price.MaxInput</code>所指定的值。</res>
            /// <exception cref="System.ArgumentException"></exception>
            public Price(double priceValue) : this((decimal)priceValue) { }        /// <summary>
            /// 以指定的价格值初始化。
            /// </summary>
            /// <param name="priceValue">价格值</param>
            /// <res>priceValue 不能小于零或大于 <code>Price.MaxInput</code>所指定的值。</res>
            /// <exception cref="System.ArgumentException"></exception>
            public Price(float priceValue) : this((decimal)priceValue) { }        /// <summary>
            /// 以指定的价格值初始化。
            /// </summary>
            /// <param name="priceValue">价格值</param>
            /// <res>priceValue 不能小于零或大于 <code>Price.MaxInput</code>所指定的值。</res>
            /// <exception cref="System.ArgumentException"></exception>
            public Price(int priceValue) : this((decimal)priceValue) { }        /// <summary>
            /// 以指定的价格值初始化。
            /// </summary>
            /// <param name="priceValue">价格值</param>
            /// <res>priceValue 不能小于零或大于 <code>Price.MaxInput</code>所指定的值。</res>
            /// <exception cref="System.ArgumentException"></exception>
            public Price(short priceValue) : this((decimal)priceValue) { }        #endregion
            
            private decimal priceValue;        /// <summary>
            /// 获取此类所接受的最大的接入值
            /// </summary>
            public static decimal MaxInput
            {
                get { return maxInput; }
            }        /// <summary>
            /// 获取价格值。此价格值保留小数点后两位。
            /// </summary>
            public decimal PriceValue
            {
                get { return priceValue; }
            }        #region Object memebers        /// <summary>
            /// 比较此实例与指定的对象表示同一价格。
            /// </summary>
            /// <param name="obj">要比较的对象</param>
            /// <returns>返回 true 表示同一对象。否则返回 false。</returns>
            public override bool Equals(object obj)
            {
                if (obj == null) return false;
                if (obj.GetType() != typeof(Price)) return false;            decimal value = ((Price)obj).priceValue;
                if (value == this.priceValue)
                    return true;
                return false;
            }        public override int GetHashCode()
            {
                return (int)priceValue;
            }        public override string ToString()
            {
                return priceValue.ToString("C");
            }        #endregion        #region Operators overloading        public static bool operator ==(Price left, Price right)
            {
                if (object.Equals(left, null) &&
                    object.Equals(right, null))
                    return true;            if (object.Equals(left, null) &&
                    !object.Equals(right, null))
                    return false;            return left.Equals(right);
            }        public static bool operator !=(Price left, Price right)
            {
                return !(left == right);
            }        public static Price operator +(Price left, Price right)
            {
                if (left == null) return new Price(right.priceValue);
                if (right == null) return new Price(left.priceValue);
                return new Price(left.priceValue + right.priceValue);
            }        public static Price operator -(Price left, Price right)
            {
                return new Price(left.priceValue - right.priceValue);
            }        public static Price operator *(Price left, int right)
            {
                return new Price(left.priceValue * right);
            }        public static Price operator *(int left, Price right)
            {
                return new Price(left * right.priceValue);
            }        public static Price operator /(Price left, int right)
            {
                return new Price(left.priceValue / right);
            }        #endregion        #region Static members        private static decimal maxInput;        /// <summary>
            /// 返回被截断的 price 值,保留小数点后两位。因为钱最多只能到“分”。
            /// </summary>
            /// <param name="price">要截断的值</param>
            /// <returns>返回被截断的 price 值,保留小数点后两位。</returns>
            private static decimal GetEffectivePrice(decimal price)
            {
                return Math.Truncate(price * 100 + (decimal)0.5) / 100;
            }        #endregion
        }
    }
      

  6.   

    作者是瞎说,Equals方法是virtual的,通过多态,你总能调用到正确的Equals方法,而Equals方法的默认实现就是RefferenceEquals。而运算符重载方法是没办法virtual的,因为运算符重载是编译期的事情。专业的表述总是比较精准。如果你还不能理解,那么尝试一下这个:int i1,i1;
    i1 = i2 = 0;
    object o1 = i1;
    object o2 = i2;Console.WriteLine( i1 == i2 );
    Console.WriteLine( o1 == o2 );
    Console.WriteLine( o1.Equals( o2 ) );
      

  7.   

    Ivony:
    我的理解和您说的是一样的。那就说,其实并没有那么讲究了?我现在还加不了分,您是等几天加分后我再结帖还是现在就结?
      

  8.   

    在大多数的时候还是要用==吧,应为在某些特定的时候我们用.Equals(object obj)的时候会出现问题