Why .NET executes code on false IF statement? - c#

I have following code:
var dateFrom = DateTime.Parse(string.Format(string.Format("01.04.{0}", dateProperty.Value.AddYears(-1).Year))
if (object.nullablebool.HasValue ? object.nullablebool.Value : false
&& (string == "V" || string == "N")
&& someDate.HasValue && object.SomeOtherDate.HasValue
&& someDate.Value.Date > dateFrom.Date)
{
>> Code
}
I have tested adding .Date or even specifiing exact year from the DateTime struct, but nothing worked.
When executing the code, even if
someDate.Value.Date > dateFrom.Date
equals 1700 > 2018, the code executed as if it was true, even though the debugger says it´s false.
When I removed this part from the condition, following code:
someDate.HasValue && object.SomeOtherDate.HasValue
When I made someDate null, so someDate.HasValue is false, the if statement still executes as true.
What did it fix? Taking these two conditions to another if:
var dateFrom = DateTime.Parse(string.Format(string.Format("01.04.{0}", dateProperty.Value.AddYears(-1).Year))
if (object.nullablebool.HasValue ? object.nullablebool.Value : false
&& (string == "V" || string == "N"))
{
if (someDate.HasValue && object.SomeOtherDate.HasValue
&& someDate.Value.Date > dateFrom.Date)
{
>> Code
}
else
{
>> Code
}
}
The code works, but it´s way too ugly. I'm running on Visual Studio 2017 Pro.
Any ideas why it behaves like that? Executing false statements?
Thanks

Your if statement performs different then expected, because it is parsed different as you wouls expect.
object.nullablebool.HasValue ? object.nullablebool.Value : false && ... is parsed as object.nullablebool.HasValue ? object.nullablebool.Value : (false && ...). So if object.nullablebool has a value, thats the result of the condition. To fix this you have to add parenthesis like this:
if ((object.nullablebool.HasValue ? object.nullablebool.Value : false )
&& (string == "V" || string == "N")
&& someDate.HasValue && object.SomeOtherDate.HasValue
&& someDate.Value.Date > dateFrom.Date)
{
// if body
}

Let's brush up your code (please, get rid of names like string, object; change them into meanful names):
// You don't want any formatting but a simple constructor
var dateFrom = new DateTime(dateProperty.Value.Year - 1, 4, 1);
// object.nullablebool == true - if object.nullablebool has value and the value is true
if (object.nullablebool == true && (string == "V" || string == "N")) {
// if someDate.Value is null the result will be false
// All we have to do is to propagate the null: ?. in someDate?.Date
if (someDate?.Date > dateFrom.Date && object.SomeOtherDate.HasValue) {
// Code
}
else {
// Code
}
}

Related

how to ignore IndexOutOfRangeException?

I need something like this:
string a = "12345"
if (a[5] == null) {
//skip error and continue the cycle
}
So the question is, how to ignore that type of error?
Make an additional length-check like:
if (a.Length >= 6 && a[5] == null) {}
but i think you mean something more like this:
if (a.Length >= 6 && a[5] == char.MinValue) {}
A char cannot be null. It can be '\0', which comes close to a "null".
Regards

How to translate conditions (without brackets) correctly?

I have condition, where are no ( ) brackets inside coded by programmer... How can I bracket such ugly coded correctly?
if( c_1 && c_2 || c_3 || c_4 && c_5 || c_6 && c_7 || c_8 || c_9 && c_10)
&& has higher precedence1 in C# than ||. That means your expression is effectively:
if ((c_1 && c_2) || c_3 || (c_4 && c_5) || (c_6 && c_7) || c_8 || (c_9 && c_10))
For further readability, I'd probably extract conditions into local variables with meaningful names. For example:
bool recentlyActive = (c_1 && c_2) || c_3;
bool passwordDisabled = (c_4 && c_5) || (c_6 && c_7);
bool userBanned = c_8 || (c_9 && c_10);
if (recentlyActive || passwordDisabled || userBanned)
{
...
}
1 Precedence in C# is documented in the specification, but it really comes directly out of the grammar. I'm glad of that documentation though, because I wouldn't want to have to read the grammar every time I wanted to understand how operators bind...

C# compiler error for single line if statement with 2 actions

It was hard to find a good title explaining the issue. I will try to explain the problem in detail. I try to use a single line if statement with 2 actions inside another if statement. However, this usage fails the parent if statement's result.
Before going into deep I have to stress that the method below returns FALSE:
draggedItem.GetComponent<PreparedItem> ().CheckPreparationAvailability ()
The method above is included inside two if clauses below. Therefore I expect the result FALSE immediately. The only changing part is the last statement, focus there.
Problematic version without parentheseses:
if (acceptedTypeID == draggedItem.CurrentTypeID.foodTypePart1
&& draggedItem.GetComponent<PreparedItem> () != null
&& draggedItem.GetComponent<PreparedItem> ().CheckPreparationAvailability () // RETURNS FALSE, DO NOT FORGET
&& rootTransform.GetComponentsInChildren<DragAndDropItem> ().Length <= 0
&& draggedItem.RootTransform.GetComponentInChildren<PlateCell>()
&& (true)? true : true) { // problem here
'if' is considered as TRUE and the inside is executed ...
}
Working version with parentheseses:
if (acceptedTypeID == draggedItem.CurrentTypeID.foodTypePart1
&& draggedItem.GetComponent<PreparedItem> () != null
&& draggedItem.GetComponent<PreparedItem> ().CheckPreparationAvailability () // RETURNS FALSE, DO NOT FORGET
&& rootTransform.GetComponentsInChildren<DragAndDropItem> ().Length <= 0
&& draggedItem.RootTransform.GetComponentInChildren<PlateCell>()
&& ((true)? true : true)) { // WORKS AS EXPECTED
'if' is considered as FALSE which is expected and the inside is NOT executed ...
}
Consider this:
bool a = true;
bool b = false;
Console.WriteLine(a && b && (true) ? true : true); // Prints true
Console.WriteLine(a && b && ((true) ? true : true)); // Prints false
This happens because the precedence of the ?: operator is such that in the first WriteLine above, it is as if you wrote this:
(a && b && (true)) ? true : true
which is always going to result in true.
The second, of course, is parenthesized so that it works as you expected.
Without the explicit parentheses the statement is executed the same way as if the parentheses would be placed as following, as everything left of the ? is considered as the condition for the inline-if:
if ((acceptedTypeID == draggedItem.CurrentTypeID.foodTypePart1
&& draggedItem.GetComponent<PreparedItem> () != null
&& draggedItem.GetComponent<PreparedItem> ().CheckPreparationAvailability () // RETURNS FALSE, DO NOT FORGET
&& rootTransform.GetComponentsInChildren<DragAndDropItem> ().Length <= 0
&& draggedItem.RootTransform.GetComponentInChildren<PlateCell>()
&& (true)) ? true : true)
So your second example is the valid solution for such a case.

How to prove to CodeContracts that the condition after a while loop is true

I'm trying to play with CodeContracts. I'm starting with a little function
public static string MyTrim(string text)
{
Contract.Requires(text != null);
Contract.Ensures(Contract.Result<string>().Length == 0 || Contract.Result<string>()[0] != ' ');
var sCurrent = text;
while (sCurrent.Length != 0 && sCurrent[0] == ' ')
{
sCurrent = sCurrent.Substring(1);
}
return sCurrent;
}
Code Contracts says to me that I didn't prove the Ensures. But After the while loop I know that the condition is false. So I know that
Scurrent.Length == 0 || Scurrent[0] != ' '
Which is exactly my ensure condition. What can i do to explain that to Code COntracts ?
I've looked into what is happening in your example and it is just a limitation of the static checker due to the disjunctive loop condition. We'll try to fix this.

Tricky if statement

Is it possible to convert this if statement into a one line statement ?
if (value != DBNull.Value)
{
dic.Add(columnName);
}
else if (!skipNullValues)
{
dic.Add(columnName);
}
if (value != DBNull.Value || !skipNullValues) dic.Add(columnName);
Use a logical OR:
if (value != DBNull.Value || !skipNullValues)
dic.Add(columnName);
I would keep the addition on a new line for clarity, although for a simple statement like this you're probably alright to drop the curly brackets. You do need to be careful if you try to add more logic in the future though obviously in the branch of the if.
if (!(value == DBNull.Value && skipNullValues))
dic.Add(columnName);
If you edit to include why making it a single line will help you might get a more suitable answer. Here are a few different approaches you could take..
First off, in a single line as you requested:
if ((value != DBNull.Value) || (value == DBNull.Value && !skipNullValues)) { dic.Add(columnName); }
Alternatively you might want to look into using ternary operators if you need something more compact.
var result = (istrue) ? (return valIfTrue) : (return valIfFalse);
More info on ternary operators:
http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx
Most likely (depending on your situation) you should consider creating a method similar to this:
public void AddColumnToDic(object value, string columnName)
bool skipNullValues = false; // todo: read from configuration
if ((value != DBNull.Value) || (value == DBNull.Value && !skipNullValues))
{
dic.Add(columnName);
}
}
and simply call it for every cell value you encounter.

Categories

Resources