Solved

VB.NET ArrayList.contains(...) Do this not use the "Equals(ByVal obj as Object)"  Method????

Posted on 2003-11-02
8
9,153 Views
Last Modified: 2008-03-03
Ok, I am extremely confused here :)  I come from a strong Java background (by strong, I mean I have a good understanding on how java works as a OOP language), and recently I have been learning how to use the .NET framework.  I am currently having problems with ArrayList Class, specifically the "Public Function Contains(ByVal value As Object) As Boolean".  

Here are parts of my current code.

in my Name Class:

 ' I am assuming this overrides the System.Object.Equals method.... if
'  it doesnt, than this is probably my problem :)

 '  Below is the code for the Name Class.  Which is in the same code 'file' as another class.. I dont
 '  think this makes a difference, but am mentioning it encase.

Public Class MyOtherClass

.... ' Other class data and methods...etc

End Class

Public Class Name
    Private First As String
    Private Last As String

    Public Sub New(ByVal First As String, ByVal Last As String)
        Firstname = First
        Lastname = Last
    End Sub

    Public Overloads Function ToString() As String
        Return Me.Last & ", " & Me.Last
    End Function

    Public Overloads Function Equals(ByVal obj As Object) As Boolean

        Dim name As Name

'  Ignoring types until I can get this part working....
'  In my test, I have ONLY sent Name objects to this method.

        name = CType(obj, Name)
        If Me.First.ToLower.Equals(name.First.ToLower) And _
           Me.Last.ToLower.Equals(name.Last.ToLower) Then
            Return True
            '  End If
        End If
        Return False
    End Function


    Public Property Firstname() As String
        Get
            Firstname = First
        End Get
        Set(ByVal Value As String)
            If Value.Equals("") Then
                Throw New MySql.MySqlException("Please Enter a valid firstname!")
            End If
            First = Value
        End Set
    End Property

    Public Property Lastname() As String
        Get
            Lastname = Last
        End Get
        Set(ByVal Value As String)
            If Value.Equals("") Then
                Throw New MySql.MySqlException("Please Enter a valid lastname!")
            End If
            Last = Value
        End Set
    End Property

End Class


'  Now in another file I have a form that has an variable:

Public myNames as Arraylist

....and here is part of that form class

'  I click on a button and it calls this function,  however, it NEVER returns true for the expression
    Private Sub addName(ByVal obj As Name)
        ' Adds the name to the mynames arraylist

        If myNames.Contains(obj) Then
            Throw New MySql.MySqlException("Name already exists in the list!")
        End If
        myNames.Add(obj)   ' Adds object to the list
        Call refreshList()       ' refreshins certain feilds.
    End Sub



I can add the same name over and over again, and whenever I use the .contains function, it never returns true....  I am either missing something very basic with how .net uses the equals method or I am missing something very simple in my own code, either way I am fed up.....so here I am.  I've also had a few drinks since I have started tonight, that could be the reason too :)
0
Comment
Question by:FaithNoMore
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
8 Comments
 
LVL 22

Expert Comment

by:_TAD_
ID: 9669074
Here is your problem...

 Private Sub addName(ByVal obj As Name)
        ' Adds the name to the mynames arraylist



.Net's Equals() and Contains() methods do NOT check the values or the contents of the objects.

Nay, they checks the objects guid/refernce number and checks to see if that that serial number appears in your list.   When you specify "ByVal" .net takes the VALUE of your object and creates a NEW object (with a new serial number/guid).


Soooo.....

Object 124-345a-3456-24 with a value of "This is string 1"

DOES NOT EQUAL

Object 876-234a-7644-11 with a value of "This is string 1"



I think you'll want to do a  ByRef call instead of byval, or perhaps do an Object.Copy()



0
 
LVL 1

Author Comment

by:FaithNoMore
ID: 9672298
I've changed my addName and removeName methods to use ByRef, but it doesnt seem to make a difference.  

When I do a ArrayList.contains() methods, how does it determine if the arraylist contains my specified object?  The .NET documentation says it uses the Equals method...I am assuming its the equals method of the object, but it doesnt seem to use my equals method at all.

Also, when I make an instance of a Name object, and look at the available methods, it shows my Equals method that takes two parameters, and the Equals method that I made (it says Overrides).  Am I overriding the wrong equals method?
0
 
LVL 22

Expert Comment

by:_TAD_
ID: 9672882



Take a peek at this code:



                  //Variable Declaration
                  char[] c;
                  string str1;
                  string str2;
                  object obj1;
                  object obj2;
                  ArrayList list = new ArrayList();

                  // Create New Char array
                  c = "String1".ToCharArray();  

                  //Create a new string with a value of "String1"
                  str1 = new string(c);  
                  //Create a new string with a value of "String1"
                  str2 = new string(c);  

                  // Create a new object with a reference to str1
                  obj1 = (object)str1;  
                  // Create a new object with a reference to str2
                  obj2 = (object)str2;  
            
                  //Add a string object to an array list with a value of "String1"
                  list.Add(new string(c));

                  // display the hash value of obj1->str1
                  Console.WriteLine("HashCode of obj1: {0}",obj1.GetHashCode().ToString());  
                  // display the hash value of obj2->str2
                  Console.WriteLine("HashCode of obj1: {0}", obj2.GetHashCode().ToString());  

                  //display GUID.Equals call for obj1 and obj2
                  Console.WriteLine("Are the system objects equal(GUID.Equals(obj1,obj2): {0}", Guid.Equals(obj1,obj2).ToString());
                  //display GUID.ReferenceEquals call for obj1 and obj2
                  Console.WriteLine("Are the system objects the same instance (GUID.ReferenceEquals(obj1,obj2): {0}", Guid.ReferenceEquals(obj1,obj2).ToString());

                  // References should NOT be equal, they are two different values
                  Console.WriteLine("Static ReferenceEquals() call, compares ref obj1 to ref obj2: {0}",ReferenceEquals(obj1, obj2).ToString());  

                  // Values should be equal, they all obtain their values from the same source
                  Console.WriteLine("Static Equals() call, compares obj1 to obj2: {0}", Equals(obj1, obj2).ToString());
                  // Values should be equal, they all obtain their values from the same source Static Vs. Instance should make no difference
                  Console.WriteLine("Instance Equals() call, compares obj2 to obj1: {0}",obj1.Equals(obj2).ToString());

                  // Check to see if array list contains the values of the object in question
                  Console.WriteLine("Array List Contains obj1: {0}",list.Contains(obj1).ToString());  
                  





Here are the results I got:


HashCode of obj1: -2105404575
HashCode of obj1: -2105404575

Are the system objects equal(GUID.Equals(obj1,obj2): True
Are the system objects the same instance (GUID.ReferenceEquals(obj1,obj2): False

Static ReferenceEquals() call, compares ref obj1 to ref obj2: False

Static Equals() call, compares obj1 to obj2: True
Instance Equals() call, compares obj2 to obj1: True

Array List Contains obj1: True


0
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 
LVL 22

Expert Comment

by:_TAD_
ID: 9672907


>When I do a ArrayList.contains() methods, how does it determine if the arraylist contains my specified object?  The .NET >documentation says it uses the Equals method...I am assuming its the equals method of the object, but it doesnt seem to >use my equals method at all.


Actually, it does NOT use the instance Equals method call, it uses the STATIC equals() method call.  The reason for this is an added level of saftey.  

If your object is Null, then the instance level equals call will throw an error, the static call actualls handles null values.


Bool b = System.Equals(null, null);
// b = true

bool b = obj1.Equals(null);
// b = false  --or-- if obj1 is null, will throw an error.   obj1 cannot be null for this to work


0
 
LVL 22

Expert Comment

by:_TAD_
ID: 9673017


The Equals() method is used to test for reference equality.  Derived value-type calsses must override this method to provide a value equality (so you can return true for identicle content even if the values are stored in different objects and different memory locations).

The ReferenceEquals method compares the object's Identity rather than its contents.


Because you are trying to compare the contents of two objects you will have to override the Equals() method on each instance.  However, you are also trying to use the ArrayList.Contains() method which uses the Static Version of the Equals(obj1, obj2) method.


What you may have to do is itterate through your arrayList and determine if any of the elements are equal to your object.


Public bool Contains(byRef object obj1, byRef ArrayList list1)
{
   // this method uses your overriden EQUALS() method to compare values

   bool contains = false;
   for(int i=0; i<list1.count; i++)
       if(obj1.Equals(list1[i])
       {
            contains = true;
            break;
       }

   return contains;
}
0
 
LVL 1

Author Comment

by:FaithNoMore
ID: 9673333
Ok, I think I understand how this all works now.  the ArrayList.contains(obj as Object ) and Arraylist.remove(obj as Object) doesn't use

- Public Overloads Shared Function ReferenceEquals(ByVal objA As Object, ByVal objB As Object) As Boolean

- Public Overloads Function Equals(ByVal obj As Object) As Boolean

- Public Overloads Shared Function Equals(ByVal objA As Object, ByVal objB As Object) As Boolean



Now, is it possible for me to override the 'static' equals method?  It would be easier if I didnt have to make two methods (one to remove objects and one to find equal objects in my Arraylist) when I could just use the contains and remove methods from Arraylist itself.  Also I havent found any reference to this 'static' method, what class does it come from?
0
 
LVL 22

Accepted Solution

by:
_TAD_ earned 50 total points
ID: 9673505



Sorry... I forgot you are using VB.Net.


Static is in C# what Shared is in VB.


// These functions are STATIC in C#

- Public Overloads Shared Function ReferenceEquals(ByVal objA As Object, ByVal objB As Object) As Boolean

- Public Overloads Shared Function Equals(ByVal objA As Object, ByVal objB As Object) As Boolean



Sorry about the confusion!!


Your ArrayList.Contains(obj1)

should use:

- Public Overloads Shared Function Equals(ByVal objA As Object, ByVal objB As Object) As Boolean


for its comparison.


I am not sure that it is possible to override a shared/static function since it exists in a layer above the class instance.  Although you should be able to "hide" the static function.

In C# the code would look like

Public static new bool Equals(object obj1);


So I would guess that the VB version would look something like

Public shared new Function Equals(byRef obj as object) as boolean.


0
 
LVL 1

Author Comment

by:FaithNoMore
ID: 9676228
What finally worked was this:

Overloads Overrides Function Equals(ByVal obj As Object) As Boolean

Just a little syntax mistake, guess I had to overload and override the method.. Learn something new everyday~ :)
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
IDE for Python 5 105
CSS question 16 62
Removing Version of .NET in Windows 10 17 124
.NET XML to Dictionary - XML has repeating node names 8 28
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question