0

So I run this piece of code:

  public class whatever
    {
        public  bool checkArray(object[] a, object x)
        {
            int goThrowArray = 0;
            bool res = false;
            while (goThrowArray != a.Length)
            {
                object tempVar  = a[goThrowArray];
                if (tempVar == x) 
                {
                    res = true;
                }
                goThrowArray++;
            }
            return res;
        }
    }

And even when x equals a[goThrowArray] It still returns false... Example:

whatever checking = new whatever();
object[] s = { 1,2,3,54,62};
Console.Write(checking.checkArray(s,3));

And then we run rest of the code in the debugger

I tried changing data types, debugging etc. But no matter what it still returns false.

Magan
  • 3
  • 1
  • 1
    A couple question arise when I look at the code. 1) why do you use a while loop instead of a for or foreach loop. 2) why are you not implementing LINQ to search through the array. 3) are the datatypes meant to be object? In your code there would be no reason to have it as object (I assume you want to implement it in a wider scope I'd once again recommend using LINQ for this) – Roe May 01 '23 at 11:39

4 Answers4

2

The problem is that the object type encapsulates the ints (which are value types) in objects (which are reference types). This process is called boxing. Objects are tested via reference equality. So, the object in the array is not the same object you are testing for. Even if both contain the same int value.

The resolution is to make the comparison with the Equals method, which is overriden for ints:

if (tempVar.Equals(x)) {
    res = true;
}

You can use a object array if you want to mix different types of objects, say int, double and string objects. But if you are only working with ints, then use a int[] instead. Then you will not have this problem.

You can even make your method generic, so that it will work with different types of arrays:

public bool CheckArray<T>(T[] a, T x)
{
    ...
}

The most common way to loop through arrays is to use a for-statement.

Also, you can return immediately when a matching entry was found. Putting this together:

public bool CheckArray<T>(T[] a, T x)
{
    for (int i = 0; i < a.Length; i++) {
        if (a[i].Equals(x)) {
            return true;
        }
    }
    return false;
}

Test:

whatever checking = new whatever();
object[] a1 = { 1, 2, 3, 54, 62 };
int[] a2 = { 1, 2, 3, 54, 62 };
string[] a3 = { "hello", "world" };

Console.WriteLine(checking.CheckArray(a1, 3));
Console.WriteLine(checking.CheckArray(a2, 3));
Console.WriteLine(checking.CheckArray(a3, "world"));
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0

Since tempVar and x are of type object the == operator resolves to object.ReferenceEquals() which always returns false for instances of boxed values. Either change that to tempVar.Equals(x) or change object to int in the signature of your function. You shouldn't use object when you know the correct type (int in this case), not only due to pitfalls such as this one, but also for performance reasons.

PMF
  • 14,535
  • 3
  • 23
  • 49
0

The first point When you find the desired object, break the while loop. And use object.Equals to compare two object

public class whatever
{
    public  bool checkArray(object[] a, object x)
    {
        int goThrowArray = 0;
        bool res = false;
        while (goThrowArray != a.Length)
        {
            object tempVar  = a[goThrowArray];
            if (tempVar.Equals(x)) 
            {
                res = true;
                break;
            }
            goThrowArray++;
        }
        return res;
    }
}
Hossein Sabziani
  • 1
  • 2
  • 15
  • 20
  • While it's a good idea, it's irrelevant here. Since res is only assigned once, it keeps it's true value once it's set. – PMF May 01 '23 at 11:34
0

Rather than using object, you should make that method generic, e.g.

public bool DoesArrayContainItem<T>(T[] a, T x)
{
    for (var i = 0; i < a.Length; i++)
    {
        if (a[i] == x)
        {
            return true;
        }
    }

    return false;
}

For one thing, that will force you to pass an item of the same type as the array. With the code you have, you could theoretically pass in an array of int and a DataTable. There would be no point doing that check and this method won't let you. It will also treat each type as itself, rather than all types as object. That means value types being treated as value types instead of being boxed.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46