Today one of my colleagues bring me a present – a new blog post!

Please take a look on the following picture and think how could execution step into the if statement. See that oldPerson is null!

She has asked everyone if anyone knows how could this happen. Do you know?

Honestly my first thought was that it is something with Nullable<T>, or maybe method Find isn’t what we think about it. I had thought that it could be LinQ method, which is somehow wrong, whatever. But nothing of that is true. :(

She did not sent the whole picture so we did not know what is the type of oldPerson object. So far we don’t know the type and we know that “!=” behaves somehow different. That’s it! Operator is wrong and I won beer. (of course not :) )

So let’s take a look on implementation of the operator:

    1 using System.Collections.Generic;
    2 
    3 namespace ConsoleApplication1
    4 {
    5     internal class Person
    6     {
    7         public string Name { get; set; }
    8 
    9         public static bool operator ==(Person left, Person right)
   10         {
   11             if (ReferenceEquals(null, right)) return false;
   12             if (ReferenceEquals(left, right)) return true;
   13             return Equals(left.Name, right.Name);
   14         }
   15 
   16         public static bool operator !=(Person left, Person right)
   17         {
   18             return !(left == right);
   19         }
   20 
   21         public bool Equals(Person obj)
   22         {
   23             return (this == obj);
   24         }
   25 
   26         public override bool Equals(object obj)
   27         {
   28             if (ReferenceEquals(this, obj)) return true;
   29             if (obj.GetType() != typeof(Person)) return false;
   30             return (this == ((Person)obj));
   31         }
   32 
   33     }
   34 
   35     class Program
   36     {
   37         static void Main(string[] args)
   38         {
   39             var persons = new List<Person>()
   40                 {
   41                     new Person(){Name = “Ivan”},
   42                     new Person(){Name = “Andriy”}
   43                 };
   44 
   45             foreach (var item in persons)
   46             {
   47                 var oldPerson = persons
   48                     .Find(x => x.Name == item.Name+“Not Andriy”);
   49 
   50                 if (oldPerson != null)
   51                 {
   52                     item.Name = oldPerson.Name;
   53                 }
   54             }
   55         }
   56     }
   57 }

Do you already see where the problem is? It is definitely in line 11: if (ReferenceEquals(null, right)) return false;
if we will get null in right object it will say that null is not equal to null.

Reason why she needs that so much complicated is because she accesses properties of the object in return condition later:
return Equals(left.Name, right.Name);