簡體   English   中英

如果“ ==運算符未定義”會怎樣?

[英]What happens if “== operator is not defined”?

如果“ ==運算符未定義”會怎樣?

例:

class a
{
    int variable = 0;
}
class b
{
    void proc()
    {
        a ref1 = new a();
        a ref2 = new a();
        bool cmp1 = ref1 == ref2;//?
        bool cmp2 = ref1 == ref1;//?
    }
}

使用結構時是否有所不同?

封送( System.Runtime.Remoting.* )對象(單個)怎么樣?

對於用戶定義的值類型 ,您的代碼將無法編譯。

具體來說,它將導致編譯失敗,並顯示以下錯誤: “運算符'=='無法應用於類型為'a'和'a'的操作數”。

“除非結構明確地使它們重載,否則==和!=運算符不能對結構進行操作。”

您必須超載他們兩個 您很可能不想在方法中使用默認的Equals() ,因為“ ...對於結構,Object.Equals(Object)的默認實現(在System.ValueType中被覆蓋的版本)執行值相等性當實現者在構造函數中覆蓋虛擬Equals方法時,其目的是提供一種更高效的方法來執行值相等性檢查,並有選擇地將比較基於某些結構的字段或屬性的子集。”

對於用戶定義的引用類型 (簡化的情況,如OP的示例):

“即使類沒有重載它們,也可以將==和!=運算符用於類。但是,默認行為是執行引用相等性檢查。在類中,如果重載Equals方法,則應重載==和!=運算符,但這不是必需的。”

如果不使運算符超載,則很可能只會進行參考相等性測試。

“簡化的情況”,因為運算符重載解析可能會選擇其他實現而不是default

//Minimal example, for demonstration only.
//No Equals(), GetHaschode() overload, no IEquatable<T>, null checks, etc..
class Program
{
    static void Main()
    {

        MyMoreDerived a = new MyMoreDerived() { fbase = 1, fderived = 3 };
        MyMoreDerived b = new MyMoreDerived() { fbase = 2, fderived = 3 };

        //Even though MyMoreDerived does not overload the operators, this
        //will succeed - the definition in MyDerived will be used.
        if (a == b)
        {
            //Reached, because the operator in MyDerived is used.
            Console.WriteLine("MyDerived operator used: a == b");
        }

        a.fderived = 2;
        b.fbase = 1;
        //a => {1, 2} 
        //b => {1, 3}
        //Since 2 != 3, the operator in MyDerived would return false.
        //However only the operator in MyBase will be used.
        if ((MyBase)a == (MyBase)b)
        {
            //Reached, because the operator in MyBase is used.
            Console.WriteLine("MyBase operator used: a == b");
        }

        b.fderived = 2;
        //a => {1, 2} 
        //b => {1, 2}
        //Now both operator definitions would compare equal,
        //however they are not used.
        if ((object)a != (object)b)
        {
            //Reached, because the default implementation is used
            //and the references are not equal.
            Console.WriteLine("Default operator used: a != b");
        }

    }

    class MyBase
    {
        public int fbase;

        public static bool operator ==(MyBase x, MyBase y)
        {
            return x.fbase == y.fbase;
        }

        public static bool operator !=(MyBase x, MyBase y)
        {
            return x.fbase != y.fbase;
        }

    }

    class MyDerived : MyBase
    {
        public int fderived;

        public static bool operator ==(MyDerived x, MyDerived y)
        {
            return x.fderived == y.fderived;
        }

        public static bool operator !=(MyDerived x, MyDerived y)
        {
            return x.fderived != y.fderived;
        }

    }

    class MyMoreDerived : MyDerived
    {
    }

}

單例在引用類型的上下文中最有意義,其目的是返回一個特定的實例。 我無法想象一個合理的情況,其中引用是相同的,但對象不等於其自身。

即使使用遠程處理,最佳做法還是將操作合同與數據合同分開。 前者通常由服務器端的MarshalByRefObject實施-實現由接口定義的操作-而后者的數據/消息類按值進行編組,並可能由客戶端和服務器共享。 如果您在數據類中重載運算符,可能不是一個大問題。 我認為,這些不應引用/調用遠程對象。

即使您提供了一個使操作符超載的自定義客戶端代理,恕我直言,將遠程調用隱藏在==!=操作符后面是一種非常糟糕的做法,也是調試的噩夢。 (如果我了解您的意圖,則不確定。)

無論它們是否指向內存中的同一對象,都可能會比較指針“ a”和“ b”。

如果需要比較那些對象的字段,則必須定義比較器功能。

您將需要從IComparable接口繼承並定義CompareTo方法。

在這里看: IComparable接口

從MSDN:

對於預定義的值類型,相等運算符(==)如果其操作數的值相等,則返回true,否則返回false。 對於字符串以外的引用類型,如果==的兩個操作數引用同一對象,則==返回true。 對於字符串類型,==比較字符串的值。

當==不被覆蓋時,我相信它會比較引用,檢查它們是否是同一對象。

例:

MyClass a = new MyClass(1);
MyClass b = new MyClass(1);
MyClass c = a;

if (a == b) // false
    ...
if (a == c) // true
    ...

因此,在上面的代碼中,cmp1為false,而cmp2為true

但是,對於用戶定義的值類型,它會比較該類型的實際值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM