0

I have the following code:

public static bool contains(Team [] ts, Team t)
{
    for(int i=0; i<ts.Length; i++)
    {
        if (ts[i]== t)
        {
            return true;
        }
    }
    return false;
}

But somehow it always returns false. When I use Equals it throws NullReferenceException and I don't know what else to do.

YAHEL
  • 1

3 Answers3

2

There are a few points in your question wich are worth discussing.

In order to compare ts[i] and t you are using the equality operator ==. By default, this operator performs a reference equality check between the two operands, put in other words this is equivalent to calling object.ReferenceEquals(ts[i], t). This means that the two operands are considered equal if and only if they are two references to the same memory location.

If this is not the equality semantic that you intend for the class Team, you need to override both the Equals and GetHashCode methods and both the operators == and !=. After that, your code will automatically use the equality semantic that you have defined in your overrides. Start from here if you need more details on this.

The second important point is the one related with the NullReferenceException. If you call t[i].Equals(t) and t[i] is a null reference then you'll get a NullReferenceException. So you have the following choices:

  • checks whether t[i] is a null reference before calling Equals
  • use the equality operator instead
  • use the static method object.Equals instead

Last but not the least, as pointed out in other answers what you are trying to do is already implemented in .NET framework and you should use the already existing Contains extension method.

Notice that when using the already existing Contains extension method you still need to override the equality members of the Team class, as explained above.

As an alternative, you can decide to use this overload of the Contains extension method which allows you to specify the desired equality semantic at the call site, by means of a custom equality comparer (an implementation of IEqualityComparer<Match> in your case). This can be useful if, for any reason, defining several different equality semantics for the Team class (based on the context) makes sense. If you always want to compare Match instances using the same equality semantic, stick with the first choice of overriding the equality members of the class (as explained above) and use the overload of Contains having one parameter only.

Enrico Massone
  • 6,464
  • 1
  • 28
  • 56
0

It is usually a good way to learn to check how .net framework implemented similiar behaviour in their code.

From .Net Source:

    // Contains returns true if the specified element is in the ArrayList.
    // It does a linear, O(n) search.  Equality is determined by calling
    // item.Equals().
    //
    public virtual bool Contains(Object item) {
        if (item==null) {
            for(int i=0; i<_size; i++)
                if (_items[i]==null)
                    return true;
            return false;
        }
        else {
            for(int i=0; i<_size; i++)
                if ( (_items[i] != null) && (_items[i].Equals(item)) )
                    return true;
            return false;
        }
    }
0

One way to do this is to create an interface with an Equals method and then the class implement that interface.

With your example:

public interface IEqualable<T>
{
    public bool Equal(T t);
}

public class Team : IEqualable<Team>
{
    public string TeamName { get; set; }
    public bool Equal(Team t2)
    {
        if(t2 is null) return false; 
        if (this.TeamName == t2.TeamName)
            return true;
        return false;
    }
}

public class Program
{
    static void Main(string[] args)
    {
        var p = new Team[3] { new Team() { TeamName = "qwe" }, new Team() { TeamName = "asd" }, new Team() { TeamName = "qq" } };
        Console.WriteLine(contains(p, new Team { TeamName = "qq" }));
    }

    public static bool contains(Team[] ts, Team t)
    {
        for (int i = 0; i < ts.Length; i++)
        {
            if (ts[i].Equal(t))
            {
                return true;
            }
        }
        return false;
    }
}

More details here

krlosmederos
  • 176
  • 3
  • 11