How to override equality?

I'm still new to operator overloading. I thought I was doing a great job until I found this problem. The NullReferenceException is thrown in a statement! =. I guess it uses it in the CompareTo method, but I'm not quite sure. If someone can point me in the right direction, I would be very grateful.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); List<Task> tasks = new List<Task>(); tasks.Add(new Task( "first", DateTime.Now.AddHours(2))); tasks.Add(new Task( "second", DateTime.Now.AddHours(4))); tasks.TrimExcess(); tasks.Sort(); } } public class Task : IComparable { public Task() { } public Task(string nameIn, DateTime dueIn) { nameOfTask = nameIn; dateDue = dueIn; } DateTime dateDue; string nameOfTask; public static bool operator <(Task t1, Task t2) { return (t1.dateDue < t2.dateDue); } public static bool operator >(Task t1, Task t2) { return (t1.dateDue > t2.dateDue); } public static bool operator ==(Task t1, Task t2) { return (t1.dateDue == t2.dateDue); } public static bool operator !=(Task t1, Task t2) { return (t1.dateDue != t2.dateDue); } public override int GetHashCode() { return Int32.Parse(this.dateDue.ToString("yyyymmddhhmmss")); } public override bool Equals(System.Object obj) { if (obj == null) return false; Task t = obj as Task; if ((System.Object)t == null) return false; return (this.dateDue == t.dateDue); } int IComparable.CompareTo(object obj) { if (obj == null) return 1; Task t = obj as Task; if (t != null) { return this.dateDue.CompareTo(t.dateDue); } else throw new ArgumentException("Object is not a Task"); } } } 

When I comment on binaory statements, the program functions as intended. My question is, how can I protect my binary operators from null references so that I can store them for manual comparisons? Thank you for your time.

+6
source share
3 answers

Both answers given so far are incorrect. The accepted answer is incorrect because it is accidentally repeated. Another answer is incorrect because it says null is not null.

Your operator implementations are not correct; they must handle zero inputs correctly.

Your implementation of GetHashCode is deeply broken; You are trying to enter a fourteen-digit number in a format that can take nine digits. Just call GetHashCode for a date; no need to go through this rigamarole turning it into a string and then turn it into a number!

The right way to write code is to use object.ReferenceEquals to compare links instead of using the == and != ; It's too easy to do random recursion.

A typical template is as follows:

 public static bool operator ==(Task t1, Task t2) { if (object.ReferenceEquals(t1, t2)) return true; // All right. We know that they are (1) not the same object, and // (2) not both null. Maybe one of them is null. if (object.ReferenceEquals(t1, null)) return false; if (object.ReferenceEquals(t2, null)) return false; // They are not the same object and both are not null. return t1.dateDue == t2.dateDue; } public static bool operator !=(Task t1, Task t2) { // Simply call the == operator and invert it. return !(t1 == t2); } public override bool Equals(object t) { return (t as Task) == this; } public override int GetHashCode() { return this.dateDue.GetHashCode(); } 

Other comparison operators remain as an exercise.

+13
source

It looks like one of the Task objects that you are comparing with != set to null . The built-in operator != Compares the links and does not interrupt, but your operator tries to dereference the task and breaks.

 public static bool operator !=(Task t1, Task t2) { if (ReferenceEquals(t1, null)) { return !ReferenceEquals(t2, null); // return true only if t2 is *not* null } if (ReferenceEquals(t2, null)) { return true; // we know that t1 is not null } return (t1.dateDue != t2.dateDue); } 

This implementation returns false when both tasks are null . You must implement symmetric zero checking in the == operator.

+3
source
  public static bool operator !=(Task t1, Task t2) { if (null == t1 || null == t2) { return false;} return (t1.dateDue != t2.dateDue); } 
-4
source

Source: https://habr.com/ru/post/913985/


All Articles