How to step into an interface method (Equals) - c#

I've implemented the iEquatable interface:
LineItem : IEquatable<LineItem>
But now I want to debug my Equals(...) method by stepping through the code. But even in debug mode, stepping in doesn't go into it (i.e. F11), and putting a breakpoint inside the method doesn't get me into it either. How can I debug it??
Not that it should be relevant but here is my Equals method:
public bool Equals(LineItem other)
{
List<bool> individuals = new List<bool>();
individuals.Add(DateTime.Equals(Expiry, other.Expiry));
individuals.Add(Code == other.Code);
individuals.Add(Type == other.Type);
individuals.Add(Class == other.Class);
Func<object, object, bool> Compare = delegate(object A, object B)
{
if (A == DBNull.Value || B == DBNull.Value)
return A == B;
else
return (double)A == (double)B;
};
individuals.Add(Compare(Strike, other.Strike));
individuals.Add(Compare(Future, other.Future));
individuals.Add(Compare(Premium, other.Premium));
individuals.Add(Compare(Volatility, other.Volatility));
individuals.Add(Compare(Volume, other.Volume));
individuals.Add(Compare(OpenInterest, other.OpenInterest));
individuals.Add(Compare(Delta, other.Delta));
return !individuals.Contains(false);
}
EDIT:
I'm calling the method from elsewhere in my code like this now:
if(!fo.Future.Equals(li))...
but that still doesn't let me debug it.

You need to take a big step back and learn how to implement equality methods correctly in the first place. C# was designed to be a "pit of success" language; that is, you should naturally "fall into" doing things the right way. Unfortunately, equality is not a "pit of success" in C#; the language designers failed to make it easy to do it right the first time.
Here's the pattern that I use when I override equality.
First, start by writing a private static method that does everything right. Everything else will use this method. Start your method by dealing with (1) the reference equality early out, and (2) null checks.
private static MyEquality(Foo x, Foo y)
{
if (ReferenceEquals(x, y)) return true;
// We now know that they are not BOTH null. If one is null
// and the other isn't then they are not equal.
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
// Now we know that they are both non-null and not reference equal.
... check for value equality here ...
}
OK, now that we have that, we can use that to implement everything else.
public override bool Equals(object y)
{
return MyEquality(this, y as Foo);
}
public override int GetHashcode()
{
// Implement GetHashcode to follow the Prime Directive Of GetHashcode:
// Thou shalt implement GetHashcode such that if x.Equals(y) is true then
// x.GetHashcode() == y.GetHashcode() is always also true.
}
public bool Equals(Foo y)
{
return MyEquality(this, y);
}
That is what is necessary to correctly implement IEquatable<T>.Equals. You should also consider overriding the == operator to be consistent:
public static bool operator ==(Foo x, Foo y)
{
return MyEquality(x, y);
}
public static bool operator !=(Foo x, Foo y)
{
return !MyEquality(x, y);
}
Now no matter whether you call object.Equals(foo, bar), foo.Equals(bar), or foo == bar, you have consistent behavior.

LineItem.Equals(a, b) is a static method call to Object.Equals(object, object); it isn't your method.
This implementation will call a.Equals(object) if you've overridden it, but you did not override it.

Related

Is there a difference between !(a == b) and a != b

I have just seen code that used if(!(a == b)) instead of the more commonly seen if(a != b) in C#. I am wondering if there is a difference between the two in C#?
In most cases, they're the same - but they don't have to be. != and == can be overloaded separately, with different logic. Here's an example:
using System;
class Test
{
// All this code is awful. PURELY FOR DEMONSTRATION PURPOSES.
public static bool operator==(Test lhs, Test rhs) => true;
public static bool operator!=(Test lhs, Test rhs) => true;
public override bool Equals(object other) => true;
public override int GetHashCode() => 0;
static void Main()
{
Test a = null;
Test b = null;
Console.WriteLine(a != b); // True
Console.WriteLine(!(a == b)); // False
}
}
In the vast majority of cases, a != b and !(a == b) will have exactly the same behavior, and a != b is almost always clearer. But it's worth being aware that they can differ.
It can get even more pathological - a != b and !(a == b) may even have different types. For example:
using System;
class Test
{
// All this code is awful. PURELY FOR DEMONSTRATION PURPOSES.
public static Test operator==(Test lhs, Test rhs) => new Test();
public static Test operator!=(Test lhs, Test rhs) => new Test();
public static string operator!(Test lhs) => "Negated";
public override string ToString() => "Not negated";
public override bool Equals(object other) => true;
public override int GetHashCode() => 0;
static void Main()
{
Test a = null;
Test b = null;
Console.WriteLine(a != b); // "Not negated"
Console.WriteLine(!(a == b)); // "Negated"
}
}
Here a != b is of type Test, but !(a == b) is of type string. Yes, this is horrible and you're unlikely to run into it in real life - but it's the kind of thing a C# compiler needs to know about.
Sure there's a difference. If ! and == and != are overloaded, then the first calls the first two operators, and the second calls the third. Those are permitted to do very different things, though it would be foolish to do so.
In fact it is common to implement overloaded == and != operators in terms of each other; you might say bool operator !=(C x, C y) => !(x == y); for example. In that case, x != y would be an infinite recursion, which is plainly different than calling !(x == y)!
Logically and conceptually there's no difference, but, since the operators can be overloaded, implementationally there may be a difference.
This highlights a general point in coding though, that any method, operator, property, whatever, should aim to do exactly "what it says on the tin". There should ideally be no surprises, no inconsistent or unexpected behaviour hidden in the implementation.

Can it returns null? (this.Result ==Result.OK)

Can this code return null?
(this.Result == Result.OK)
Can this line (or a similar one) return anything except than true or false (e.g. null)?
(this.Result == Result.OK)
OK; let's take this piece by piece:
this.(anything)
That can fail if this is null - which it never should be, but theoretically can be if you are evil - so we could fail with a NullReferenceException.
this.Result
if that is a property accessor (a get), then it could fail in any way it likes - it could throw an exception.
Result.OK
now; if this is an enum, it is just a ldc - but if this .OK is actually a static property accessor, it can certainly fail with any exception it likes.
this.Result == Result.OK
We need to know what .Result returns; if we assume that it returns a Result (we don't know that), then we still need to know what Result is: if it is an enum it'll be a direct numeric equality check; if it is a nullable-enum, "lifted" equality rules apply, but still resolve cleanly. If it is a custom type that overloads ==, then anything could happen and any exception could result.
But here's the crazy: == does not need to return a bool:
public static int operator ==(int x, Foo foo)
{
return 0; // DO NOT EVER DO THIS
}
public static int operator !=(int x, Foo foo)
{
return 0; // DO NOT EVER DO THIS
}
If you the Result type is custom, then (this.Result == Result.OK) can return anything it wants:
using System;
class P
{
static void Main()
{
new P().Test();
}
public Result Result { get; set; }
public void Test()
{
var x = (this.Result == Result.OK);
Console.WriteLine(x.GetType().Name); // Int32
}
}
public class Result
{
public static Result OK { get { return null; } }
public static int operator ==(Result x, Result y)
{
return 42; // DO NOT EVER DO THIS
}
public static int operator !=(Result x, Result y)
{
return 0; // DO NOT EVER DO THIS
}
}
Finally, we need to consider that something obscure like a ThreadAbortException, OutOfMemoryException or StackOverflowException could happen at any time.
But in sane conditions: yes, it can only result in a bool result.
As == is comparison operator,this statement always return a Bool
The == operator will return true or false at all times. That is a boolean.
It should be noted that the "or another" in your question can indeed return something other than true or false. Unless you tell us what the other you have in mind is we can't answer that.
This answer assumes that the expression does return something. As Marc Gravell points out exceptions may stop it returning at all (depending on how you consider returning).
Also Marc kindly pointed out that == can be overloaded. It is almost certainly a bad idea to do so and change the return type but it seems it is theoretically possible.
No, == can only returns true or false.
The statement itself will return a bool true or false.
The object involved:
this.Result
Could potentially be null, perhaps this is what you're referring to when you ask whether it can return null
There are 2 possible outcomes.
The line is executed and returns true
the line is executed and it returns false

Enumerable.Distinct - What methods does your custom class have to implement for it to work?

I've implemented every function that MSDN says is necessary, plus some additional comparison interfaces - nothing seems to work. Following is code (optimized for LinqPad).
The resulting output is all 4 items, not 2 like I expect.
Please don't post work arounds as answers - I want to know how Distinct works
void Main()
{
List<NameClass> results = new List<NameClass>();
results.Add(new NameClass("hello"));
results.Add(new NameClass("hello"));
results.Add(new NameClass("55"));
results.Add(new NameClass("55"));
results.Distinct().Dump();
}
// Define other methods and classes here
public class NameClass : Object
, IEquatable<NameClass>
, IComparer<NameClass>
, IComparable<NameClass>
, IEqualityComparer<NameClass>
, IEqualityComparer
, IComparable
{
public NameClass(string name)
{
Name = name;
}
public string Name { get; private set; }
public int Compare(NameClass x, NameClass y)
{
return String.Compare(x.Name, y.Name);
}
public int CompareTo(NameClass other)
{
return String.Compare(Name, other.Name);
}
public bool Equals(NameClass x, NameClass y)
{
return (0 == Compare(x, y));
}
public bool Equals(NameClass other)
{
return (0 == CompareTo(other));
}
public int GetHashCode(NameClass obj)
{
return obj.Name.GetHashCode();
}
public new int GetHashCode()
{
return Name.GetHashCode();
}
public new bool Equals(object a)
{
var x = a as NameClass;
if (null == x) { return false; }
return Equals(x);
}
public new bool Equals(object a, object b)
{
if (null == a && null == b) { return true; }
if (null == a && null != b) { return false; }
if (null != a && null == b) { return false; }
var x = a as NameClass;
var y = b as NameClass;
if (null == x && null == y) { return true; }
if (null == x && null != y) { return false; }
if (null != x && null == y) { return false; }
return x.Equals(y);
}
public int GetHashCode(object obj)
{
if (null == obj) { return 0; }
var x = obj as NameClass;
if (null != x) { return x.GetHashCode(); }
return obj.GetHashCode();
}
public int CompareTo(object obj)
{
if (obj == null) return 1;
NameClass x = obj as NameClass;
if (x == null)
{
throw new ArgumentException("Object is not a NameClass");
}
return CompareTo(x);
}
}
How Distinct works:
There is at least no implementation of Object.GetHashCode() which is used for initial comparison of objects: basic version of Distinct compares (actually puts in dictionary) by Object.GetHashCode first, than if hash code matches by Object.Equals.
To be precise Enumerable.Distinct(this IEnumerable source) uses EqualityComparer<NameClass>.Default to finally check for equality (note that if hash codes don't match it will not reach that portion of the comparison which is why your sample does not work).
The default equality comparer, Default, is used to compare values of the types that implement the IEquatable generic interface.
EqualityComparer.Default in turn actually allows to use class without IEquatable<T> at all falling back directly to Object.Equals:
The Default property checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
So for basic Distinct to work you just need correct version of Equals/GetHashCode. IEquatable is optional, but must match behavior of GetHashCode in the class.
How to fix:
Your sample have public new int GetHashCode() method, which likely should be public override int GetHashCode() (Same for Equals).
Note that public new int... does not mean "override", but instead "create new version of the method that hides old one". It does not impact callers that call method via pointer to parent object.
Personally I think new should rarely be used in defining methods. Some suggestions when it is useful are covered in Usecases for method hiding using new.
You don't have to implement any interface, just GetHashCode and Equals methods correctly:
public class NameClass
{
public NameClass(string name)
{
Name = name;
}
public string Name { get; private set; }
public override bool Equals(object obj)
{
var other = obj as NameClass;
return other != null && other.Name == this.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
Enumerable.Distinct<TSource> Method:
It uses the default equality comparer, Default, to compare values.
EqualityComparer.Default:
The Default property checks whether type T implements the System.IEquatable<T> interface and, if so, returns an EqualityComparer<T> that uses that implementation. Otherwise, it returns an EqualityComparer<T> that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
IEquatable<T> Interface:
If you implement IEquatable<T>, you should also override the base class implementations of Object.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable<T>.Equals method.
Overriding methods:
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.
So your code should look like this:
public class NameClass : IEquatable<NameClass>
{
public NameClass(string name)
{
Name = name;
}
public string Name { get; private set; }
// implement IEquatable<NameClass>
public bool Equals(NameClass other)
{
return (other != null) && (Name == other.Name);
}
// override Object.Equals(Object)
public override bool Equals(object obj)
{
return Equals(obj as NameClass);
}
// override Object.GetHashCode()
public override GetHashCode()
{
return Name.GetHashCode();
}
}
So, first off, Distinct will, as per it's documentation, use EqualityComparer<T>.Default to compare objects if no custom equality comparer is provided (you provided none).
EqualityComparer<T>.Default, as per its documentation, will look to see if the object implements IEquatable<T>, if it does it will use that implementation of Equals.
Regardless of whether or not the type implements IEquatable<T>, EqualityComparer<T>.Default will use the object.GetHashCode method to get the has code of the object. IEquatable<T>, unfortunately, does not force you to also override the object's GetHashCode implementation, and in your case, while you do implement IEquatable<T>, your code does not override the object's GetHashCode implementation.
As a result of this Distinct is actually using the proper Equals method for your type, but it's using the wrong GetHashCode method. Whenever you're hashing objects and that type has an Equals and GetHashCode implementation that's out of sync problems ensue. What's happening is that in whatever hash based collection it's sending the two "equal" objects to different buckets, so they never even get to the point where their Equals methods are called on each other. If you happened to get lucky and there was a hash collection and the objects were coincidentally sent to the same bucket, then, since the Equals method is what you intended it would actually work, but the odds of that happening are...very low. (In this specific case, about 2/2147483647, or
9.3e-10.
While you do provide a new GetHashCode method in NameClass, it is hiding the object implementation, not overriding it. If you change your GetHashCode implementation to use override rather than new then your code will work.
I just realized I messed up my sample code - my class derives from DependencyObject, not Object. I can't override thew GetHashCode or Equals functions because the DependencyObject class is sealed.

Distinct() returns duplicates with a user-defined type

I'm trying to write a Linq query which returns an array of objects, with unique values in their constructors. For integer types, Distinct returns only one copy of each value, but when I try creating my list of objects, things fall apart. I suspect it's a problem with the equality operator for my class, but when I set a breakpoint, it's never hit.
Filtering out the duplicate int in a sub-expression solves the problem, and also saves me from constructing objects that will be immediately discarded, but I'm curious why this version doesn't work.
UPDATE: 11:04 PM Several folks have pointed out that MyType doesn't override GetHashCode(). I'm afraid I oversimplified the example. The original MyType does indeed implement it. I've added it below, modified only to put the hash code in a temp variable before returning it.
Running through the debugger, I see that all five invocations of GetHashCode return a different value. And since MyType only inherits from Object, this is presumably the same behavior Object would exhibit.
Would I be correct then to conclude that the hash should instead be based on the contents of Value? This was my first attempt at overriding operators, and at the time, it didn't appear that GetHashCode needed to be particularly fancy. (This is the first time one of my equality checks didn't seem to work properly.)
class Program
{
static void Main(string[] args)
{
int[] list = { 1, 3, 4, 4, 5 };
int[] list2 =
(from value in list
select value).Distinct().ToArray(); // One copy of each value.
MyType[] distinct =
(from value in list
select new MyType(value)).Distinct().ToArray(); // Two objects created with 4.
Array.ForEach(distinct, value => Console.WriteLine(value));
}
}
class MyType
{
public int Value { get; private set; }
public MyType(int arg)
{
Value = arg;
}
public override int GetHashCode()
{
int retval = base.GetHashCode();
return retval;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
MyType rhs = obj as MyType;
if ((Object)rhs == null)
return false;
return this == rhs;
}
public static bool operator ==(MyType lhs, MyType rhs)
{
bool result;
if ((Object)lhs != null && (Object)rhs != null)
result = lhs.Value == rhs.Value;
else
result = (Object)lhs == (Object)rhs;
return result;
}
public static bool operator !=(MyType lhs, MyType rhs)
{
return !(lhs == rhs);
}
}
You need to override GetHashCode() in your class. GetHashCode must be implemented in tandem with Equals overloads. It is common for code to check for hashcode equality before calling Equals. That's why your Equals implementation is not getting called.
Your suspicion is correct,it is the equality which currently just checks the object references. Even your implementation does not do anything extra, change it to this:
public override bool Equals(object obj)
{
if (obj == null)
return false;
MyType rhs = obj as MyType;
if ((Object)rhs == null)
return false;
return this.Value == rhs.Value;
}
In you equality method you are still testing for reference equality, rather than semantic equality, eg on this line:
result = (Object)lhs == (Object)rhs
you are just comparing two object references which, even if they hold exactly the same data, are still not the same object. Instead, your test for equality needs to compare one or more properties of your object. For instance, if your object had an ID property, and objects with the same ID should be considered semantically equivalent, then you could do this:
result = lhs.ID == rhs.ID
Note that overriding Equals() means you should also override GetHashCode(), which is another kettle of fish, and can be quite difficult to do correctly.
You need to implement GetHashCode().
It seems that a simple Distinct operation can be implemented more elegantly as follows:
var distinct = items.GroupBy(x => x.ID).Select(x => x.First());
where ID is the property that determines if two objects are semantically equivalent. From the confusion here (including that of myself), the default implementation of Distinct() seems to be a little convoluted.
I think MyType needs to implement IEquatable for this to work.
The other answers have pretty much covered the fact that you need to implement Equals and GetHashCode correctly, but as a side note you may be interested to know that anonymous types have these values implemented automatically:
var distinct =
(from value in list
select new {Value = value}).Distinct().ToArray();
So without ever having to define this class, you automatically get the Equals and GetHashCode behavior you're looking for. Cool, eh?

How do I implement IEqualityComparer on an immutable generic Pair struct?

Currently I have this (edited after reading advice):
struct Pair<T, K> : IEqualityComparer<Pair<T, K>>
{
readonly private T _first;
readonly private K _second;
public Pair(T first, K second)
{
_first = first;
_second = second;
}
public T First { get { return _first; } }
public K Second { get { return _second; } }
#region IEqualityComparer<Pair<T,K>> Members
public bool Equals(Pair<T, K> x, Pair<T, K> y)
{
return x.GetHashCode(x) == y.GetHashCode(y);
}
public int GetHashCode(Pair<T, K> obj)
{
int hashCode = obj.First == null ? 0 : obj._first.GetHashCode();
hashCode ^= obj.Second == null ? 0 : obj._second.GetHashCode();
return hashCode;
}
#endregion
public override int GetHashCode()
{
return this.GetHashCode(this);
}
public override bool Equals(object obj)
{
return (obj != null) &&
(obj is Pair<T, K>) &&
this.Equals(this, (Pair<T, K>) obj);
}
}
The problem is that First and Second may not be reference types (VS actually warns me about this), but the code still compiles. Should I cast them (First and Second) to objects before I compare them, or is there a better way to do this?
Edit:
Note that I want this struct to support value and reference types (in other words, constraining by class is not a valid solution)
Edit 2:
As to what I'm trying to achieve, I want this to work in a Dictionary. Secondly, SRP isn't important to me right now because that isn't really the essence of this problem - it can always be refactored later. Thirdly, comparing to default(T) will not work in lieu of comparing to null - try it.
Your IEqualityComparer implementation should be a different class (and definately not a struct as you want to reuse the reference).
Also, your hashcode should never be cached, as the default GetHashcode implementation for a struct (which you do not override) will take that member into account.
It looks like you need IEquatable instead:
internal struct Pair<T, K> : IEquatable<Pair<T, K>>
{
private readonly T _first;
private readonly K _second;
public Pair(T first, K second)
{
_first = first;
_second = second;
}
public T First
{
get { return _first; }
}
public K Second
{
get { return _second; }
}
public bool Equals(Pair<T, K> obj)
{
return Equals(obj._first, _first) && Equals(obj._second, _second);
}
public override bool Equals(object obj)
{
return obj is Pair<T, K> && Equals((Pair<T, K>) obj);
}
public override int GetHashCode()
{
unchecked
{
return (_first != null ? _first.GetHashCode() * 397 : 0) ^ (_second != null ? _second.GetHashCode() : 0);
}
}
}
If you use hashcodes in comparing methods, you should check for "realy value" if the hash codes are same.
bool result = ( x._hashCode == y._hashCode );
if ( result ) { result = ( x._first == y._first && x._second == y._second ); }
// OR?: if ( result ) { result = object.Equals( x._first, y._first ) && object.Equals( x._second, y._second ); }
// OR?: if ( result ) { result = object.ReferenceEquals( x._first, y._first ) && object.Equals( x._second, y._second ); }
return result;
But there is littlebit problem with comparing "_first" and "_second" fields.
By default reference types uses fore equality comparing "object.ReferenceEquals" method, bud they can override them. So the correct solution depends on the "what exactly should do" the your comparing method. Should use "Equals" method of the "_first" & "_second" fields, or object.ReferenceEquals ? Or something more complex?
Regarding the warning, you can use default(T) and default(K) instead of null.
I can't see what you're trying to achieve, but you shouldn't be using the hashcode to compare for equality - there is no guarantee that two different objects won't have the same hashcode. Also even though your struct is immutable, the members _first and _second aren't.
First of all this code violates SRP principle. Pair class used to hold pairs if items, right? It's incorrect to delegate equality comparing functionality to it.
Next let take a look at your code:
Equals method will fail if one of the arguments is null - no good. Equals uses hash code of Pair class, but take a look at the definition of GetHashCode, it just a combination of pair members hash codes - it's has nothing to do with equality of items. I would expect that Equals method will compare actual data. I'm too busy at the moment to provide correct implementation, unfortunately. But from the first look, you code seems to be wrong. It would be better if you provide us description of what you want to achieve. I'm sure SO members will be able to give you some advices.
Might I suggest the use of Lambda expressions as a parameter ?
this would allow you to specify how to compare the internal generic types.
I don't get any warning when compiling about this but I assume you are talking about the == null comparison? A cast seems like it would make this all somewhat cleaner, yes.
PS. You really should use a separate class for the comparer. This class that fills two roles (being a pair and comparing pairs) is plain ugly.

Categories

Resources