? operator shows an "unreachable code detected" warning - c#

I'm implementing an equals method and one of the equality conditions is that two dates match. My current code is:
public override bool Equals(object obj)
{
if (obj == null || obj.GetType() != typeof(Appointment))
return false;
Appointment other = obj as Appointment;
bool equal = true;
equal = (this.date == null ? (other.date == null) : (this.date.Equals(other.date)));
//more stuff here
return equal
}
when I try to build this, I get a warning pointing to the other.date==null statement saying unreachable code detected
however when I replace it with this:
if (this.date == null)
equal = other.date == null;
else
equal = (this.date.Equals(other.date));
I get no such warning
what am I missing?

I don't get such warning when the datatype is "object", but I get it as soon as I changed the datatype to "DateTime". So it has to do with the datatype. Datetime can't be null. Anyway you should check if "other" is null:
Appointment other = obj as Appointment;
bool equal = false; // init to false is better
if (other != null)
{
equal = (this.date == null ? (other.date == null) : (this.date.Equals(other.date)));
}
return equal;

Related

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);

Is it possible to modify the boolean value returned when checked if an instance of an object is null?

I was wondering if it is possible to modify the boolean value returned when checked if an instance of an object is null, for example (I know this is wrong and incomplete, just want to give you a reference):
Main:
SuperObject obj = new SuperObject();
if (obj == null) Console.WriteLine("It is null lol!");
SuperObject:
public bool destroyed = false;
public static bool operator ==(SuperObject A, object B)
{
if (A != null && B == null && destroyed == true)
return true;
}
So if the expression (A == null) is checked and A is NOT null but A.destroyed is TRUE, it will return that (A == null) is TRUE.
Basically I want (A == null) to be TRUE when:
A is really null OR A.destroyed = null; The default value for other comparisons.
I would recommend doing this instead:
public static bool IsDestroyed(SuperObject a) {
return (a == null || a.destroyed);
}
Your way would be very confusing to new developers.

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..

Error when assigning a boolean value

I am getting an error while assigning a value.
My code is:
protected bool ValidateProfile()
{
bool blnFirstName = false;
bool blnLastName = false;
bool blnEMail = false;
//(error on line below: "The left-hand side of an assignment must be a variable, property or indexer")
ValidateProfile() = false;
if txtFName != ""
blnFName = true;
if txtLName != ""
blnLName = true;
if txtEMail != ""
blnEMail = true;
if (blnFName) && (blnLName) && (blnEMail))
ValidateProfile = true;
}
How do I assign a boolean value to ValidateProfile ?
Thanks
You want
return false;
In C#, we don't assign values to the function name in order to return a value.
If you want to set the return value at a different point in time from when you return from the method, then you should do something like this:
bool retVal; // Defaults to false
if (condition)
retVal = true;
if (otherCondition)
retVal = false;
if (thirdCondition)
retVal = true;
return retVal;
You can't assign a value to a function. You need return false;
As others have pointed out, in C# you use return instead of MyFunction = x. In this scenario, you can assign the result of your final check to a boolean and return it:
bool retVal = (blnFName) && (blnLName) && (blnEMail);
return retVal;
Alternatively, you could just skip the assignment altogether:
return (blnFName) && (blnLName) && (blnEMail);
EDIT: I noticed you are using hungarian notation, which implies that txtFName is a TextBox. Keep in mind that C# doesn't have default properties like VB. If it is a TextBox, it will never equal "", because it's not of type System.String. I'm guessing you actually wanting to evaluate txtFName.Text
Change that last line to:
return false;
Although it seems you're always returning false here. Is there an option to return true?
Just a side note besides all the returns...
You may want to change this:
if txtFName != ""
To check if the String.IsEmptyOrNull(txtFName.Text)
Or at least initialize your variables to either null or String.Empty.
Just an FYI though.
You want to return false
Alright, taking the code you posted:
protected bool ValidateProfile()
{
return !String.IsNullOrEmpty(txtFName) && !String.IsNullOrEmpty(txtLName) && !String.IsNullOrEmpty(txtEMail);
}
Or
protected bool ValidateProfile()
{
bool returnValue = true;
if(String.IsNullOrEmpty(txtFName))
{
returnValue=false;
}
else if(String.IsNullOrEmpty(txtLName))
{
returnValue = false;
}
else if(String.IsNullOrEmpty(txtEMail))
{
returnValue = false;
}
return returnValue;
}
Though you could just return false as soon as you find an invalid field.
Not a C# programmer, but can't you just write:
return (txtFName != "") && (txtLName != "") && (txtEMail != "");
for the body of the function?

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