How can i implement == and check for null in c# [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicates:
What is “Best Practice” For Comparing Two Instances of a Reference Type?
How do I check for nulls in an '==' operator overload without infinite recursion?
I have a class called "Criterion" and i want to implement == operator,but I'm struggling with the following problem :
When i implement the == operator, I'm checking if one or both of my instances are null, but when i do it, it causes a recursive call for == and then i get "StackOverflow" (he he) exception.
Technically i can implement the Equals operator and not override the ==, but the code will be much more readable if i implement the == operator.
Here is my code :
public static bool operator == (Criterion c1, Criterion c2)
{
if (null == c1)
{
if (null == c2)
return true;
return false;
}
if (null == c2)
return false;
if ((c1.mId == c2.mId) && (c1.mName == c2.mName))
return true;
return false;
}

Try ReferenceEquals:
public static bool operator ==(Criterion c1, Criterion c2) {
var nullC1 = ReferenceEquals(null, c1);
var nullC2 = ReferenceEquals(null, c2);
if (nullC1 && nullC2)
return true;
if (!nullC1 && !nullC2)
if (c1.mId == c2.mId && c1.mName == c2.mName)
return true;
return false;
}

I'd do it like this:
bool isC1Null = Object.Equals(c1, null)
bool isC2Null = Object.Equals(c2, null)
if (isC1Null ^ isC2Null)
{
return false
}
if (isC1Null && isC2Null)
{
return true
}
//your code

Related

What is the clean way for checking null equality for a class implementing IEqualityComparer<T>? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
This is what I could come up with to check for null equality. It works but it is Shreak looking. The following is valid for this example:
x != null and y == null returns false;
x == null and y != null returns false;
x == null and y == null returns true;
x.ToString() == y.ToString() returns true;
I guess I could code the above but I still feel there is a cleaner way to solve it.
public bool Equals(ConvertibleData x, ConvertibleData y)
{
if (x == null)
{
if (y == null)
{
return true;
}
return false;
}
if (y == null)
{
return false;
}
return x.ToString() == y.ToString(); //Disregard the ToString, this coult be any comparer validation
}
I usually use this pattern where the comparands can be null:
public bool Equals(ConvertibleData? x, ConvertibleData? y)
{
if (ReferenceEquals(x, y))
return true;
if (x is null || y is null)
return false;
return x.ToString() == y.ToString(); //Disregard the ToString, this coult be any comparer validation
}
I like this pattern:
if (x is null && y is null)
return true;
if (x is null || y is null);
return false;
// Check x's properties against y's properties
All your answers are better than code in the question above. I found this example from the official microsoft reference website about IEqualityComparer:
link
public bool Equals(Box b1, Box b2)
{
if (b2 == null && b1 == null)
return true;
else if (b1 == null || b2 == null)
return false;
else if(b1.Height == b2.Height && b1.Length == b2.Length
&& b1.Width == b2.Width)
return true;
else
return false;
}

Generic Compare function [duplicate]

This question already has answers here:
Check two object, of unknown type, for equality, comparing all their fields
(2 answers)
Closed 3 years ago.
I'm trying to make a generic compare function to see if two instances of a class which may hold member variables that are a List<>.
bool IsEqual<T>(T a, T b)
{
var props = typeof(T).GetProperties();
foreach(var property in props)
{
var aVal = property.GetValue(a);
var bVal = property.GetValue(b);
if (aVal as System.Collections.IEnumerable != null)
{
// Convert into lists, do something with SequenceEqual and possibly recursive call to IsEqual
}
if (!Equals(aVal,bVal)) return false;
}
return true;
}
I'm not sure how to convert a given member variable to a proper list, so I can do a SequenceEqual on it to compare the lists.
The classes that I will use in IsEqual() are not native to my program but comes from a DLL.
Does the following code work for you?
public static bool DeepEquals(object a, object b)
{
if (a == null)
{
if (b == null) return true;
else return false;
}
else if (b == null) return false;
if (object.ReferenceEquals(a, b)) return true;
var comparable = a as IComparable;
if (comparable != null)
{
return comparable.CompareTo(b) == 0;
}
var aType = a.GetType();
var bType = b.GetType();
if (aType != bType) return false;
var aEnumerable = a as IEnumerable;
if (aEnumerable != null)
{
var bEnumerable = (IEnumerable)b;
var aEnumerator = aEnumerable.GetEnumerator();
var bEnumerator = bEnumerable.GetEnumerator();
while (true)
{
var amoved = aEnumerator.MoveNext();
var bmoved = bEnumerator.MoveNext();
if (amoved != bmoved) return false;
if (amoved == false && bmoved == false) return true;
if (DeepEquals(aEnumerator.Current, bEnumerator.Current) == false) return false;
}
}
var props = aType.GetProperties();
foreach (var prop in props)
{
if (DeepEquals(prop.GetValue(a), prop.GetValue(b)) == false) return false;
}
return true;
}
Note that this method is not generic. Implementing a generic method is more difficult because you don't know at runtime the type of properties nor the type of the items of collections.

if then else vs the ternary operator ( ? :) in c#

this.value1 and c.value1 can both be either null or non-null. So a total of 4 combinations to test. value2 can also be null or non-null.
Can the if-then-else's below be replaced by something shorter like use the ternary operator ( if then else using the ? : operators) - and would that be a bad practice for this specific case because we are testing 4 combinations for value1 and value2?
public override bool Equals(object obj)
{
bool value1_check = false;
bool value2_check = false;
var c = obj as ObjectType;
if (this.value1 != null)
value1_check = this.value1.Equals(c.value1);
else if ((this.value1 == null) && (c.value1 == null))
value1_check = true;
else if ((this.value1 == null) && (c.value1 != null))
value1_check = c.value1.Equals(this.value1);
if (this.value2 != null)
value2_check = this.value2.Equals(c.value2);
else if ((this.value2 == null) && (c.value2 == null))
value2_check = true;
else if ((this.value2 == null) && (c.value2 != null))
value2_check = c.value2.Equals(this.value2);
return (value1_check && value2_check);
}
You can call Object.Equals(), which already does all that.
return Equals(this.Value1, c.Value1)
&& Equals(this.Value2, c.Value2);
Actually, you might want the ?? Operator.
var lhs= this.value1 ?? c.value1 ?? null;
var rhs = c.value1 ?? this.value1 ?? null;
var value1Check = lhs == rhs
Should do the same thing as yours, but almost 100% less readable!
If your still wondering about the ternary option.
value1_check= this.value1!=null? this.value1.Equals(c.value1):(c.value1!=null?c.value.Equals(this.value):value1_check=true);

Return a variable as soon as it is set to a certain value. Equality overloading

I am overloading the Equality method for value comparison and was wondering if there is a clean way to return false as soon as one of the value comparisons returns false. For example, here is the basic idea:
public class MyClass
{
private int _valOne;
private int _valTwo;
private int _valThree;
public MyClass(int valOne, int valTwo, int valThree)
{
_valOne = valOne;
_valTwo = valTwo;
_valThree = valThree;
}
public override bool Equals(object obj)
{
// If the object is null return false
if (obj == null)
{
return false;
}
// If the object is not of MyClass type return false
MyClass myClass = obj as MyClass;
if (myClass == null)
{
return false;
}
// Now compare all the field values
bool areEqual = false;
areEqual = (this._valOne == myClass._valOne);
areEqual = (this._valTwo == myClass._valTwo);
areEqual = (this._valThree == myClass._valThree);
return areEqual;
}
}
Say the _valOne's do not equal. The most efficient way to compare is to return false as soon as it is known two values are not equal. Something like the following...
// Now compare all the field values
bool areEqual = false;
areEqual = (this._valOne == myClass._valOne);
if (!areEqual)
{
return false;
}
areEqual = (this._valTwo == myClass._valTwo);
if (!areEqual)
{
return false;
}
areEqual = (this._valThree == myClass._valThree);
return areEqual;
So now after the comparison of the _valOnes no more value comparisons are made. This seems very repetitive, clunky, and (most importantly) horrible for readability. I want to know if there is any way this code can be reduced to the same effect in a clean way without the use of the && operator.
You can take advantage of the short-circuiting nature of the logical AND (&&) operator, like this:
return this._valOne == myClass._valOne
&& this._valTwo == myClass._valTwo
&& this._valThree == myClass._valThree;
As soon as any one of the comparisons evaluates to false, the whole condition evaluates to false. If all three are true, the condition returns true.
Use an and condition:
areEqual = (this._valOne == myClass._valOne)
&& (this._valTwo == myClass._valTwo)
&& (this._valThree == myClass._valThree);
&& implements short-circuiting by default.
Another way could be to do this:
if (this._valOne != myClass._valOne)
return false;
if (this._valTwo != myClass._valTwo)
return false;
if (this._valThree != myClass._valThree)
return false;
return true;
A matter of choice I guess. I'd think the && one is more readable..

Determine value of object in C#

What would be the best way to determine if an object equals number zero (0) or string.empty in C#?
EDIT: The object can equal any built-in System.Value type or reference type.
Source Code:
public void MyMethod(object input1, object input2)
{
bool result = false;
object compare = new object();
if(input != null && input2 != null)
{
if(input1 is IComparable && input2 is IComparable)
{
//do check for zero or string.empty
//if input1 equals to zero or string.empty
result = object.Equals(input2);
//if input1 not equals to zero or string.empty
result = object.Equals(input1) && object.Equals(input2); //yes not valid, but this is what I want to accomplish
}
}
}
Using Jonathan Holland code sample with a minor modification, here is the solution that worked:
static bool IsZeroOrEmpty(object o1)
{
bool Passed = false;
object ZeroValue = 0;
if(o1 != null)
{
if(o1.GetType().IsValueType)
{
Passed = (o1 as System.ValueType).Equals(Convert.ChangeType(ZeroValue, o1.GetType()))
}
else
{
if (o1.GetType() == typeof(String))
{
Passed = o1.Equals(String.Empty);
}
}
}
return Passed;
}
What's wrong with this?
public static bool IsZeroOrEmptyString(object obj)
{
if (obj == null)
return false;
else if (obj.Equals(0) || obj.Equals(""))
return true;
else
return false;
}
Michael, you need to provide a little bit more information here.
strings can be compared to null or string.Empty by using the method
string x = "Some String"
if( string.IsNullOrEmpty(string input) ) { ... }
int, decimals, doubles (and other numeric value-types) can be compared to 0 (zero) with a simple == test
int x = 0;
if(x == 0) { ... }
You can also have nullable value-types also by using the ? operator when you instantiate them. This allows you to set a value type as null.
int? x = null;
if( !x.HasValue ) { }
For any other object, a simple == null test will tell you if its null or not
object o = new object();
if( o != null ) { ... }
Hope that sheds some light on things.
Not quite sure the reasoning behind this, because .Equals is reference equality on reference types, and value equality on value types.
This seems to work, but I doubt its what you want:
static bool IsZeroOrEmpty(object o1)
{
if (o1 == null)
return false;
if (o1.GetType().IsValueType)
{
return (o1 as System.ValueType).Equals(0);
}
else
{
if (o1.GetType() == typeof(String))
{
return o1.Equals(String.Empty);
}
return o1.Equals(0);
}
}
Do you mean null or string.empty, if you're talking about strings?
if (String.IsNullOrEmpty(obj as string)) { ... do something }
Oisin
In the first case by testing if it is null. In the second case by testing if it is string.empty (you answered your own question).
I should add that an object can never be equal to 0. An object variable can have a null reference though (in reality that means the variable has the value of 0; there is no object in this case though)
obj => obj is int && (int)obj == 0 || obj is string && (string)obj == string.Empty

Categories

Resources