[英]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.