The Object object is the root object of the entire .NET Framework. Since everything inherits from Object, the methods there can be found in all other objects, but they're usually overridden so the implementation changes a lot. There are only six public methods in Object. (They're introduced in the Quick Tip: The Object Object.) Two of the six are used for testing equality with other objects.
The Equals method
The basic idea in using the Equals method is just what you might expect:
Dim a, b, c As Object a = "1" b = "1" c = "2" ' Returns True Console.WriteLine(a.Equals(b).ToString) ' Returns False Console.WriteLine(a.Equals(c).ToString)
Although you can create your own object (Class), inherit Object, and override Equals to make it do whatever you want (in your Class), Microsoft's rule book states that all implementations of Equals (including Microsoft's own implementations) have to follow these rules (I've added some simplification - see MSDN for the detailed version):
- x.Equals(x) returns true
- x.Equals(y) returns the same value as y.Equals(x)
- x.Equals(y) returns true if both x and y are NaN
- (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true
- Successive calls to x.Equals(y) return the same value as long as the objects referenced by x and y are not modified
- x.Equals(Nothing) returns false
But there can be some surprises. For example, this would seem to contradict the second rule:
Dim s As Short = 0 Dim l As Long = 0 Console.WriteLine(s.Equals(l)) ' False Console.WriteLine(l.Equals(s)) ' True
Microsoft's documentation for the Equals method specifies that it returns True only if "obj" is an instance of the object (Short or Long). In the first case, "l" is not an instance of Short, so Equals returns False. In the second case, VB.NET "casts" the "l" variable to a Short behind the scenes, then executes the Equals method and returns True.
This is a bit technical, but doubters can run ILDASM against the .exe after building a project with this code. The IL code for the first Equals is:
call instance bool [mscorlib]System.Int16::Equals(object)
The IL code for the second Equals is:
call instance bool [mscorlib]System.Int64::Equals(int64)
So, it's always a good idea to understand how Equals is implemented in the specific object you're using.
This method is used to find out whether two instances of an object are the same instance. Sound confusing? It can be! The first question I had was, "When would you ever use such a method?" The documentation at Microsoft isn't much help. (This example is based on theirs, but I think it makes the point more clearly.)
Dim o As String = "ABCD" Dim p As String = "ABCD" Dim q As String = "EFGH" Console.WriteLine(Object.ReferenceEquals(o, p)) p = q Console.WriteLine(Object.ReferenceEquals(p, q)) Console.WriteLine(Object.ReferenceEquals(o, p)) ' True ' True ' False
This is super for demonstrating that VB.NET is effecient and doesn't waste memory resources for objects that don't need any new memory. Initially, "o" and "p" are the same instance. There is no reason to waste memory if there is no difference in the strings. But when a new string is assigned to one of them (p = q), those two strings are then the same instance, but the first two are not anymore.
I was not able to find an actual example of ReferenceEquals being used for something other than an example to demonstrate what VB.NET was doing with memory resources. (I did find one in a different tutorial, but I was able to get the same result with simpler code by eliminating the use of ReferenceEquals.) If someone knows of one, send me an email.