The output of the below code is as following:
not equal
equal
Note the difference in type of x and xx and that == operator overload is only executed in the second case and not in the first.
Is there a way I can overload the == operator so that its always executed when a comparison is done on between MyDataObejct instances.
Edit 1:# here i want to override the == operator on MyDataClass , I am not sure how I can do it so that case1 also executes overloaded == implementation.
class Program {
static void Main(string[] args) {
// CASE 1
Object x = new MyDataClass();
Object y = new MyDataClass();
if ( x == y ) {
Console.WriteLine("equal");
} else {
Console.WriteLine("not equal");
}
// CASE 2
MyDataClass xx = new MyDataClass();
MyDataClass yy = new MyDataClass();
if (xx == yy) {
Console.WriteLine("equal");
} else {
Console.WriteLine("not equal");
}
}
}
public class MyDataClass {
private int x = 5;
public static bool operator ==(MyDataClass a, MyDataClass b) {
return a.x == b.x;
}
public static bool operator !=(MyDataClass a, MyDataClass b) {
return !(a == b);
}
}
No, basically. == uses static analysis, so will use the object ==. It sounds like you need to use object.Equals(x,y) instead (or x.Equals(y) if you know that neither is null), which uses polymorphism.
Here is a description on how to override Equals and the == operator:
http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx
This is how it looks (provided that you have already made an overload of Equals()):
public static bool operator ==(MyDataClass a, MyDataClass b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Otherwise use equals
return a.Equals(b);
}
public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to MyDataClass return false.
MyDataClass p = obj as MyDataClass;
if ((System.Object)p == null)
{
return false;
}
return (x == p.x);
}
Related
This seems incredibly basic, but I couldn't find any other answers on this particular note. In declaring a == operator in C#, you must also declare the != operator. Obviously every case may vary based on type, but if a type has explicit equality or does not, is it reasonable to declare != as simply !(a == b)? Is there a reason NOT to do this? For example:
public static bool operator ==(Point p1, Point p2)
{
return ((p1.X == p2.x) && (p1.Y == p2.Y));
}
public static bool operator !=(Point p1, Point p2)
{
return !(p1 == p2);
}
There is a good example from Microsoft Docs: How to: Define Value Equality for a Type covering important aspects of defining equality for types.
In the following example, for x!=y you see it's simply returning !(x==y):
using System;
class TwoDPoint : IEquatable<TwoDPoint>
{
// Readonly auto-implemented properties.
public int X { get; private set; }
public int Y { get; private set; }
// Set the properties in the constructor.
public TwoDPoint(int x, int y)
{
if ((x < 1) || (x > 2000) || (y < 1) || (y > 2000))
{
throw new System.ArgumentException("Point must be in range 1 - 2000");
}
this.X = x;
this.Y = y;
}
public override bool Equals(object obj)
{
return this.Equals(obj as TwoDPoint);
}
public bool Equals(TwoDPoint p)
{
// If parameter is null, return false.
if (Object.ReferenceEquals(p, null))
{
return false;
}
// Optimization for a common success case.
if (Object.ReferenceEquals(this, p))
{
return true;
}
// If run-time types are not exactly the same, return false.
if (this.GetType() != p.GetType())
{
return false;
}
// Return true if the fields match.
// Note that the base class is not invoked because it is
// System.Object, which defines Equals as reference equality.
return (X == p.X) && (Y == p.Y);
}
public override int GetHashCode()
{
return X * 0x00010000 + Y;
}
public static bool operator ==(TwoDPoint lhs, TwoDPoint rhs)
{
// Check for null on left side.
if (Object.ReferenceEquals(lhs, null))
{
if (Object.ReferenceEquals(rhs, null))
{
// null == null = true.
return true;
}
// Only the left side is null.
return false;
}
// Equals handles case of null on right side.
return lhs.Equals(rhs);
}
public static bool operator !=(TwoDPoint lhs, TwoDPoint rhs)
{
return !(lhs == rhs);
}
}
I'm having troubles getting my MyClass == operator's method reference when specifying the comparison type while using Type.GetMethod(), here is my code:
public class MyClass
{
public object Value { get; set; }
public MyClass(object inVal = null)
{
Value = inVal;
}
public static bool operator ==(MyClass a, string b)
{
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null)) return false;
// Return true if the fields match:
return Convert.ToString(a.Value) == b;
}
public static bool operator !=(MyClass a, string b)
{
return !(a == b);
}
public static bool operator ==(MyClass a, bool b)
{
// If one is null, but not both, return false.
if ((object)a == null) return false;
// Return true if the fields match:
return Convert.ToBoolean(a.Value) == b;
}
public static bool operator !=(MyClass a, bool b)
{
return !(a == b);
}
}
A call to
var methodInfo = typeof(MyClass).GetMethod("op_Equality", new Type[] { typeof(bool) } )
or
var methodInfo = typeof(MyClass).GetMethod("op_Equality", new Type[] { typeof(string) } )
, returns NULL, why is that? I expected a reference to the operator.
The equality/inequality operators works on two types,
(in your case the class type and the bool/string type),
you need to pass also the class type (in the correct order expected)
Type t1 = typeof(MyClass);
var methodInfo1 = t1.GetMethod("op_Equality",
new Type[] { t1, typeof(bool) } );
var methodInfo2 = t1.GetMethod("op_Equality",
new Type[] { t1, typeof(string) } );
The normal method expects a public instance method to look for. As yours are static methods, you should use an overload of GetType that you can pass a BindingFlags parameter of Static.
I need a way to represent an integer number that can be infinite. I'd prefer not to use a floating point type (double.PositiveInfinity) since the number can never be fractional and this might make the API confusing. What is the best way to do this?
Edit: One idea I haven't seen yet is using int? with null representing infinity. Are there any good reasons not to do this?
If you don't need the full range of integer values, you can use the int.MaxValue and int.MinValue constants to represent infinities.
However, if the full range of values is required, I'd suggest either creating a wrapper class or simply going for doubles.
An example partial implementation along the lines of the comments of SLaks and others (feedback welcome):
Usage:
int x = 4;
iint pi = iint.PositiveInfinity;
iint ni = iint.NegativeInfinity;
Assert.IsTrue(x + pi == iint.PositiveInfinity);
Assert.IsTrue(pi + 1 == iint.PositiveInfinity);
Assert.IsTrue(pi + (-ni) == iint.PositiveInfinity);
Assert.IsTrue((int)((iint)5) == 5);
Implementation:
public struct iint
{
private readonly int _int;
public iint(int value)
{
if(value == int.MaxValue || value == int.MinValue)
throw new InvalidOperationException("min/max value reserved in iint");
_int = value;
}
public static explicit operator int(iint #this)
{
if(#this._int == int.MaxValue || #this._int == int.MinValue)
throw new InvalidOperationException("cannot implicit convert infinite iint to int");
return #this._int;
}
public static implicit operator iint(int other)
{
if(other == int.MaxValue || other == int.MinValue)
throw new InvalidOperationException("cannot implicit convert max-value into to iint");
return new iint(other);
}
public bool IsPositiveInfinity {get { return _int == int.MaxValue; } }
public bool IsNegativeInfinity { get { return _int == int.MinValue; } }
private iint(bool positive)
{
if (positive)
_int = int.MaxValue;
else
_int = int.MinValue;
}
public static readonly iint PositiveInfinity = new iint(true);
public static readonly iint NegativeInfinity = new iint(false);
public static bool operator ==(iint a, iint b)
{
return a._int == b._int;
}
public static bool operator !=(iint a, iint b)
{
return a._int != b._int;
}
public static iint operator +(iint a, iint b)
{
if (a.IsPositiveInfinity && b.IsNegativeInfinity)
throw new InvalidOperationException();
if (b.IsPositiveInfinity && a.IsNegativeInfinity)
throw new InvalidOperationException();
if (a.IsPositiveInfinity)
return PositiveInfinity;
if (a.IsNegativeInfinity)
return NegativeInfinity;
if (b.IsPositiveInfinity)
return PositiveInfinity;
if (b.IsNegativeInfinity)
return NegativeInfinity;
return a._int + b._int;
}
public static iint operator -(iint a, iint b)
{
if (a.IsPositiveInfinity && b.IsPositiveInfinity)
throw new InvalidOperationException();
if (a.IsNegativeInfinity && b.IsNegativeInfinity)
throw new InvalidOperationException();
if (a.IsPositiveInfinity)
return PositiveInfinity;
if (a.IsNegativeInfinity)
return NegativeInfinity;
if (b.IsPositiveInfinity)
return NegativeInfinity;
if (b.IsNegativeInfinity)
return PositiveInfinity;
return a._int - b._int;
}
public static iint operator -(iint a)
{
if (a.IsNegativeInfinity)
return PositiveInfinity;
if (a.IsPositiveInfinity)
return NegativeInfinity;
return -a;
}
/* etc... */
/* other operators here */
}
Your API can use a convention that int.MaxValue represents positive infinity value and int.MinValue - negative infinity.
But you still need to document it somewhere and, may be you will need some operations with your infinite integer:
/// <summary>
/// Making int infinity
/// ...
/// </summary>
public static class IntExtension
{
public const int PositiveInfinity = int.MaxValue;
public const int NegativeInfinity = int.MinValue;
public static bool IsPositiveInfinity(this int x)
{
return x == PositiveInfinity;
}
public static bool IsNegativeInfinity(this int x)
{
return x == NegativeInfinity;
}
public static int Operation(this int x, int y)
{
// ...
return PositiveInfinity;
}
}
Another partial implementation (I see Jack was faster):
struct InfinityInt
{
readonly int Value;
InfinityInt(int value, bool allowInfinities)
{
if (!allowInfinities && (value == int.MinValue || value == int.MaxValue))
throw new ArgumentOutOfRangeException("value");
Value = value;
}
public InfinityInt(int value)
: this(value, false)
{
}
public static InfinityInt PositiveInfinity = new InfinityInt(int.MaxValue, true);
public static InfinityInt NegativeInfinity = new InfinityInt(int.MinValue, true);
public bool IsAnInfinity
{
get { return Value == int.MaxValue || Value == int.MinValue; }
}
public override string ToString()
{
if (Value == int.MinValue)
return double.NegativeInfinity.ToString();
if (Value == int.MaxValue)
return double.PositiveInfinity.ToString();
return Value.ToString();
}
public static explicit operator int(InfinityInt ii)
{
if (ii.IsAnInfinity)
throw new OverflowException();
return ii.Value;
}
public static explicit operator double(InfinityInt ii)
{
if (ii.Value == int.MinValue)
return double.NegativeInfinity;
if (ii.Value == int.MaxValue)
return double.PositiveInfinity;
return ii.Value;
}
public static explicit operator InfinityInt(int i)
{
return new InfinityInt(i); // can throw
}
public static explicit operator InfinityInt(double d)
{
if (double.IsNaN(d))
throw new ArgumentException("NaN not supported", "d");
if (d >= int.MaxValue)
return PositiveInfinity;
if (d <= int.MinValue)
return NegativeInfinity;
return new InfinityInt((int)d);
}
static InfinityInt FromLongSafely(long x)
{
if (x >= int.MaxValue)
return PositiveInfinity;
if (x <= int.MinValue)
return NegativeInfinity;
return new InfinityInt((int)x);
}
public static InfinityInt operator +(InfinityInt a, InfinityInt b)
{
if (a.IsAnInfinity || b.IsAnInfinity)
{
if (!b.IsAnInfinity)
return a;
if (!a.IsAnInfinity)
return b;
if (a.Value == b.Value)
return a;
throw new ArithmeticException("Undefined");
}
return FromLongSafely((long)a.Value + (long)b.Value);
}
public static InfinityInt operator *(InfinityInt a, InfinityInt b)
{
if (a.IsAnInfinity || b.IsAnInfinity)
{
if (a.Value == 0 || b.Value == 0)
throw new ArithmeticException("Undefined");
return (a.Value > 0) == (b.Value > 0) ? PositiveInfinity : NegativeInfinity;
}
return FromLongSafely((long)a.Value * (long)b.Value);
}
// and so on, and so on
}
C# has a type for this the BigInteger class is unlimited size
http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx
If you want the class to have a representation of infinity -- then wrap BigInteger in a class that gives it an infinity flag.
You will have to redefine all standard operators and conversions to get this to work.
How exactly to have operations on infinity work depends on your domain.
(For example in some forms of math you would like 2 x infinity = infinity and in some you don't).
How the details are implemented really depend on your domain problem and are not clear from your question.
Is it possible to perform union/except on Lists of Objects where the instance of objects are not necessarily the same but they are functionally equivalent?
What I mean is if I have a class like this,
Class A
{
String a;
int b;
double c;
}
And I had the following Lists:
A foo = new A() {"a",2,3.4}
A bar = new A() {"a",2,3.4}
List<A> firstList = new List<A>() { foo }
List<A> secondList = new List<A>() { bar }
How can I perform firstList.Except/Union on secondList if firstList and secondList had completely different object instances but the fields/properties of the objects are exactly the same?
You need to overload the Equals method of your class.
Right now, the way that it checks for equality is by checking the reference. There's a way to fix that, by overriding the Equals method:
class A
{
string a;
int b;
double c;
public override bool Equals(object obj)
{
A aobj = obj as A;
if (aobj == null) return false;
return a == aobj.a && b == aobj.b && c == aobj.c;
}
}
However, for these functions to perform at their best, you also need to override the GetHashCode method, too. Like this:
class A
{
string a;
int b;
double c;
public override bool Equals(object obj)
{
return a == obj.a && b == obj.b && c == obj.c;
}
public override int GetHashCode()
{
unchecked { return 17 * (a ?? "").GetHashCode() * b * c.GetHashCode(); }
}
}
Simply override the object.Equals method to tell the world when to treat your objects as equal. Your class A should look something like this:
class A
{
string a;
int b;
double c;
public override bool Equals(object obj)
{
if (!(obj is A)) return obj.Equals(this); // defer to other object
A other = (A)obj;
return a == other.a && b == other.b && c == other.c; // check field equality
}
public override int GetHashCode()
{
int hc = 13;
hc += a.GetHashCode() * 27;
hc += b.GetHashCode() * 27;
hc += c.GetHashCode() * 27;
}
}
Adding little more to previous answers. Overriding Equals will require overriding == and !=
public class A
{
String a;
int b;
double c;
public override bool Equals(object obj)
{
if (object.ReferenceEquals(null, obj))
{
return false;
}
if (object.ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != typeof(A))
{
return false;
}
var other = obj as A;
return string.Equals(this.a, other.a) && this.b == other.b && this.c == other.b;
}
public override int GetHashCode()
{
if (string.IsNullOrEmpty(a))
{
return this.b.GetHashCode() ^ this.c.GetHashCode();
}
return this.a.GetHashCode() ^ this.b.GetHashCode() ^ this.c.GetHashCode();
}
public static bool operator ==(A left, A right)
{
if (object.ReferenceEquals(left, right))
{
return true;
}
if (object.ReferenceEquals(null, left))
{
return false;
}
if (object.ReferenceEquals(null, right))
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(A left, A right)
{
return !(left == right);
}
}
You can use LINQ to Objects to create intersections and unions on lists - and there is no need to override Equals and GetHashCode. Use the Enumerable.Intersect and Enumerable.Except methods:
public class A
{
public String a;
public int b;
public double c;
}
A foo = new A() {a = "a", b = 2, c = 3.4};
A bar = new A() {a = "a", b = 2, c = 3.4};
List<A> firstList = new List<A>() { foo };
List<A> secondList = new List<A>() { bar };
firstList.Except(secondList);
firstList.Intersect(secondList);
The output in this case is:
same entries:
>> IEnumerable<A> (1 item) 4
>> a b c
>> a 2 3,4
You can make combinations firstList.Method(secondsList) and vice versa.
You could event write a custom Comparer - IEqualityComparer in order to compare complex object types.
This question already has answers here:
How do I check for nulls in an '==' operator overload without infinite recursion?
(13 answers)
Closed 9 years ago.
I overloaded the == operator on my class as follows:
public static bool operator ==(Table pt1, Table pt2) {
return Compare(pt1, pt2) == 0 && pt1.TableName == pt2.TableName;
}
Compare will work just as the strcmp does in c++, returning an integer. Problem is that if I do an if (MY_CLASS == null), it will call my == operator, and thus my Compare function. What is the alternatiev? to put an check on pt1 and pt2 to see if they are null? Or just in pt2?
You should checkout Microsoft's guidelines for implementing the '==' operator and also for overriding 'Equals()'.
Adapting their example you'd want something like:
public static bool operator ==(Table a, Table b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return Compare(a, b) == 0 && a.TableName == b.TableName;
}
You will need the null checks to get the correct behaviour. The clearest way to add this check in my opinion is to call object.ReferenceEquals(x, null), since it is a straight non-polymorphic method call and presumably fairly efficient.
Just add this line to your operator:
if ((object)pt1 == null || (object)pt2 == null) return false;
The (object) cast is there to prevent recursion (from calling object.== instead of MY_CLASS.==.
Although I'm not sure of the conditions that should arise when comparing null to null.
I asked a similar question here. Have a look at it.
public bool Equals(ClauseBE other)
{
if (this._id == other._id)
{
return true;
}
return false;
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return base.Equals(obj);
}
if (!(obj is ClauseBE))
{
throw new InvalidCastException("The 'obj' argument is not a ClauseBE object.");
}
return Equals(obj as ClauseBE);
}
public override int GetHashCode()
{
return this._id.GetHashCode();
}
public static bool operator ==(ClauseBE a, ClauseBE b)
{
if (ReferenceEquals(a, null) && ReferenceEquals(b, null))
{
return true;
}
if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
{
return false;
}
return a.Equals(b);
}
public static bool operator !=(ClauseBE a, ClauseBE b)
{
return !(a == b);
}