.NET學習之“==”、“Equals”、“IComparable”
對於內建值型別,“==”判斷的是兩個物件的代數“值”是否相等。它會根據需要自動進行必要的型別轉換,並根據兩個物件的“值”是否相等返回true或者false;Equals則需要“值”和“型別”都一樣。
而對於使用者定義的值型別(如 struct),如果沒有過載“==”操作符,“==”將是不能夠使用的。
int a = 5;
int b = 5;
Console.WriteLine("值型別,同值同型別:" + (a == b));//True
Console.WriteLine("值型別,同值同型別:" + a.Equals(b));//True
int va = 1;
double vb = 1;
Console.WriteLine("值型別,同值不同型別:" + (va == vb));//True
Console.WriteLine("值型別,同值不同型別:" + va.Equals(vb));//False
先提供一個自定義類,下面的程式碼需要用到
類Circle
class CircleCenter
{
public int X;
public int Y;
public CircleCenter()
{
}
public CircleCenter(int x,int y)
{
X = x;
Y = y;
}
}
class circle
{
public double radius = 0;
public circlecenter center = new circlecenter();
}
對於引用型別,“==”預設行為是看兩個物件是否引用同一物件,但是.NET Framework中的類很多對“==”進行了過載,例如String類的==與Equals的行為相同,判斷兩個字串的內容是否相等。所以在應用中,對於系統定義的引用型別建議不要使用==操作符,以免程式出現與預期不同的執行結果。
Equals預設行為也是判斷兩者是否引用同一物件
Circle aa = new Circle();
aa.Radius = 10;
物件的相互複製不會導致物件自身被複制,其結果是兩個物件變數指向同一個物件,
Circle bb = aa;
Circle cc = new Circle();
Console.WriteLine("bb.Radius:" + bb.Radius); //10
bb.Radius = 15;
cc.Radius = 15;
Console.WriteLine("aa.Radius:" + aa.Radius); //15
Console.WriteLine(aa == cc); //引用型別 False
Console.WriteLine(aa.Equals(cc)); //引用型別 False
Console.WriteLine(aa.Radius == cc.Radius); //值型別 True
Console.WriteLine(aa.Radius.Equals(cc.Radius)); //值型別 True
Console.WriteLine("aa == bb:" + (aa == bb));//True
Console.WriteLine("aa.Equals(bb):" + aa.Equals(bb));//True
Console.WriteLine("aa.Radius == bb.Radius:" + (aa.Radius == b.Radius));//True
Console.WriteLine("aa.Radius.Equals(bb.Radius):"+ aa.Radius.Equals(bb.Radius));//True
對於一些自定義的類有時候是需要比較的,比方說平面幾何中的圓,只要半徑是相等的就可以認為是相等的,但預設的“==”和“Equals”均是不行的。
.NET Framework基礎類為兩個物件的比較提供了IComparable介面,其含義是:實現了IComparable介面的物件即可相互比較,該介面只定義了一個公共方法int Compareto(object obj)
實現了IComparable介面的Circle
class Circle:IComparable
{
public double Radius = 0;
public CircleCenter center = new CircleCenter();
#region IComparable 成員
public int CompareTo(object obj)
{
//throw new NotImplementedException();
if (!(obj is Circle))
{
throw new ArgumentException("只能對比Circle物件");
}
if ((obj as Circle).Radius == this.Radius)
{
return 1;
}
else
{
return 0;
}
}
#endregion
}
這樣就可以用aa.CompareTo(cc) 就是相等的,因為半徑是一樣的。不過習慣了使用Equals比較,這個不太順手,在重寫Equals方法吧,在上述Circle中再加入以下程式碼
重寫Equals方法
public override bool Equals(object obj)
{
//return base.equals(obj);
if (this.CompareTo(obj) == 0)
return true;
else
return true;
}
這樣就可以直接使用Equals方法比較了。程式執行後有個小提示“重寫了Object.Equals(object o)但不重寫Object.GetHashCode()”,把滑鼠放到Circle附近,這個沒有在“錯誤列表”顯示,再重寫GetHashcode()吧(關於這個暫時不清楚,主要參考書籍,等在查詢別的資料後補充)
當然,也可以過載“==”運算子(如果過載了“==”,也需要過載“!=”)
過載“==”“!=”
public static bool perator ==(Circle obj1, Circle obj2)
{
return obj1.Equals(obj2);
}
public static bool operator !=(Circle obj1, Circle obj2)
{
return !(obj1.Equals(obj2));
}
重寫“Equals”不需要實現IComparable也是可以的,不知道為什麼要實現,直接重寫Equals不就行了?或許書上只是為了說明IComparable這個介面的存在!
最後附上全部程式碼(其中重寫GetHashCode()方法的程式碼只是為了說明問題)
完整程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication7
{
class CustomEqual
{
static void Main()
{
int a = 5;
int b = 5;
Console.WriteLine("值型別,同值同型別:" + (a == b));
Console.WriteLine("值型別,同值同型別:" + a.Equals(b));
Console.WriteLine("");
int va = 1;
double vb = 1;
Console.WriteLine("值型別,同值不同型別:" + (va == vb));
Console.WriteLine("值型別,同值不同型別:" + va.Equals(vb));
Circle aa = new Circle();
aa.Radius = 10;
aa.center = new CircleCenter(10, 10);
Circle bb = aa;
Console.WriteLine("bb.Radius:" + bb.Radius);
bb.Radius = 15;
Console.WriteLine("aa.Radius:" + aa.Radius);
Circle cc = new Circle();
cc.Radius = 15;
cc.center = new CircleCenter(10, 10);
Console.WriteLine("");
Console.WriteLine("aa == bb:" + (aa == bb));
Console.WriteLine("aa.Equals(bb):" + aa.Equals(bb));
Console.WriteLine("aa.Radius == bb.Radius:" + (aa.Radius == bb.Radius));
Console.WriteLine("aa.Radius.Equals(bb.Radius):"+ aa.Radius.Equals(bb.Radius));
Console.WriteLine("");
Console.WriteLine("aa == cc :" + (aa == cc));
Console.WriteLine("aa.Equals(cc):" + aa.Equals(cc));
Console.WriteLine("aa.Radius == cc.Radius:" + (aa.Radius == cc.Radius));
Console.WriteLine("aa.Radius.Equals(cc.Radius):" + aa.Radius.Equals(cc.Radius));
Console.WriteLine("aa.center == cc.center :" + (aa.center == cc.center));
Console.WriteLine("aa.center.Equals(cc.center):" + aa.center.Equals(cc.center));
Console.ReadKey();
}
}
class CircleCenter
{
public int X;
public int Y;
public CircleCenter()
{
}
public CircleCenter(int x,int y)
{
X = x;
Y = y;
}
}
//class circle
//{
// public double radius = 0;
// public circlecenter center = new circlecenter();
//}
class Circle:IComparable
{
public double Radius = 0;
public CircleCenter center = new CircleCenter();
#region IComparable 成員
public int CompareTo(object obj)
{
//throw new NotImplementedException();
if (!(obj is Circle))
{
throw new ArgumentException("只能對比Circle物件");
}
if ((obj as Circle).Radius == this.Radius)
{
return 1;
}
else
{
return 0;
}
}
#endregion
public override bool Equals(object obj)
{
//return base.equals(obj);
if (this.CompareTo(obj) == 0)
return true;
else
return true;
}
public static bool perator ==(Circle obj1, Circle obj2)
{
return obj1.Equals(obj2);
}
public static bool operator !=(Circle obj1, Circle obj2)
{
return !(obj1.Equals(obj2));
}
public override int GetHashCode()
{
return (int)Radius;
//return base.GetHashCode();
}
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-622785/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- AFNetworking之AFNetworkReachabilityManager深入學習
- JAVA程式設計習慣之equals對比Java程式設計
- AFNetworking之AFURLSessionManager深入學習Session
- AFNetworking之AFSecurityPolicy深入學習
- AFNetworking之AFURLRequestSerialization深入學習
- AFNetworking之AFURLResponseSerialization深入學習
- Netty學習筆記之ChannelHandlerNetty筆記
- C#之Equals與==C#
- Kubernetes學習之Metrics-ServerServer
- Netty學習之ChannelHandler&ChannelPipelineNetty
- Asp.Net MVC 學習心得 之 Html HelperASP.NETMVCHTML
- centos5.4之netstat學習筆記CentOS筆記
- 學習ThinkPHP,學習OneThinkPHP
- 【ASP.net】Equals 和 == 的區別ASP.NET
- ML.NET 示例:深度學習之整合TensorFlow深度學習
- Kubernetes 網路學習之 Cilium 與 eBPFeBPF
- ASP.NET MVC學習之模型驗證篇ASP.NETMVC模型
- .Net 反射學習反射
- Java物件之間的比較之equals和==Java物件
- 從零開始netty學習筆記之BIONetty筆記
- 從零開始netty學習筆記之protobufNetty筆記
- 學習排序演算法(二):Pairwise方法之RankNet排序演算法AI
- 從零開始netty學習筆記之netty簡單demoNetty筆記
- 前端學習之Bootstrap學習前端boot
- 學而習之,成就學習
- “==”、“equals()”、“hashcode()”之間的祕密
- .NET Core學習筆記(8)——Entity Framework Core之Database First筆記FrameworkDatabase
- .NET Core學習筆記(9)——Entity Framework Core之Code First筆記Framework
- 深度學習與圖神經網路學習分享:CNN 經典網路之-ResNet深度學習神經網路CNN
- Kubernetes學習之旅
- Kubernetes學習系列
- 學習 Log4net
- Juniper-Netscreen學習
- Netty原始碼學習系列之5-NioEventLoop的run方法Netty原始碼OOP
- 深度學習經典卷積神經網路之AlexNet深度學習卷積神經網路
- Netty原始碼學習系列之4-ServerBootstrap的bind方法Netty原始碼Serverboot
- Netty----什麼是Netty學習Netty
- Java學習之LinkedHashMap學習總結JavaHashMap