Solved

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

Posted on 2003-11-02
8
9,072 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
  • 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
 
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
asp.net mvc5 3 38
.net VBA word safemode 1 24
Code enhancement 5 13
Getfiles in vb.net 28 22
IP addresses can be stored in a database in any of several ways.  These ways may vary based on the volume of the data.  I was dealing with quite a large amount of data for user authentication purpose, and needed a way to minimize the storage.   …
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

760 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now