I am applying AND operation (&&) between two nullable boolean (bool?) but it is giving me error that
Operator && cannot be applied to operands of type bool? and bool?
How do i apply and operation in my statement that contains two nullable bools?
Also if i have a dialog result like
dialog.ShowDialog () == DialogResult.OK
How can I convert it to nullable bool as i need to put '&&' operator with this in an if condition whose other operand returns a nullable bool?
Here is code:
if (dialog.ShowDialog () == DialogResult.OK && CheckProjectPath(dialog.FileName, true))
the second operand in this if condition is a nullable bool.
How do i apply and operation in my statement that contains two nullable bools?
Well, what do you want to happen? The reason this is illegal is because bad things happen if the first operand is null.
What does x && y mean for nullable Booleans x and y? Well, what does a nullable Boolean mean in the first place? A nullable Boolean means one of three things:
The condition is definitely true
The condition is definitely false
The condition is true or false but we do not know which one
So what does x && y mean? It means "evaluate y only if condition x is true", but if x is nullable then we might not know whether the condition represented by x is true or not.
For example, suppose we have:
gotMoneyInZurich = SalesForNovemberWereMoreThanAMillionBucks() &&
TryToDepositAMillionBucksInASwissBankAccount();
If SalesForNovemberWereMoreThanAMillionBucks is false, then don't try to deposit the money, and we know we have no money in the bank. If it is true, then try to deposit the money; if that fails, then we don't have money in Zurich; if it succeeds, we do.
Now suppose that not all the salespeople have reported their sales figures for November yet. Do we know whether sales for November were more than a million bucks? No. November is in the past; either the sales were, or they weren't more than a million bucks, but right now we don't know. The correct answer is not "false", the correct answer is not "true": the correct answer is "we don't know": null.
So what should this do if null is returned by the first operand? We don't know whether sales were more than a million bucks, so is the right thing to do to try to deposit the money, or to not try to deposit the money? Should you take action on the basis of missing information, or not?
The compiler has no ability to decide this question for you. If you want to not deposit the money if the result is unknown, then you have to say that:(SalesForNovemberWereMoreThanAMillionBucks() ?? false) means "if the result was null, treat it as though it were false".
Similarly, if you say:
if(x && y)
Frob();
and x is true, and y is null, then what should you do? You are saying "Frob only if x and y are both true. x is true, and we don't know whether y is true or not". So should you Frob or not? You don't know. The compiler doesn't know either. If what you want to say is "Frob if x is true and y is either true or null" then say that:
if(x && (y ?? true))
Frob();
Or, "frob if x is true and y is true, but not if y is null" then say that:
if(x && (y ?? false))
Frob();
Now, if you are not using the && operator for the purposes of short-circuiting evaluation then don't use the && operator in the first place. Use the & operator; it always evaluates both sides, so there is no ambiguity here. It is perfectly legal to say x & y if x and y are nullable bools. You still can't use that thing in an if of course; that requires a bool, not a nullable bool. But you can say:
bool? result = x & y;
where x and y are nullable bools.
You can use something like
bool? b1 = ...;
bool? b2 = ...;
bool b = (b1 ?? true) && (b2 ?? false);
You have to pick your own defaults.
How can I convert it to nullable bool as i need to put '&&' operator with this in an if condition whose other operand returns a nullable bool?
You should go the other way: You can't do operations on a nullable operand so you have to try to convert from bool? to bool. The operator ?? is very useful here:
if (dialog.ShowDialog () == DialogResult.OK
&& CheckProjectPath(dialog.FileName, true) ?? false)
Regarding the "null-coalescing operator" ?? :
int? a, b, c;
...
int d = a ?? b ?? c ?? -1;
if a, b and c are all null then d becomes -1. If anyone of them is not null, the first value is used.
I'm just guessing you can try
if ((dialog.ShowDialog() == DialogResult.OK )&&
(CheckProjectPath(dialog.FileName, true) == true ) )
if (dialog.ShowDialog () == DialogResult.OK &&
CheckProjectPath(dialog.FileName, true).GetValueOrDefault())
The && operation is not defined for nulls. Therefore you have to make sure that both booleans are not nullable, and the easiest way to do that is to call the GetValueOrDefault() method of the nullable boolean.
if (dialog.ShowDialog () == DialogResult.OK)
{
var checkProjectPath = CheckProjectPath(dialog.FileName, true);
if (checkProjectPath.HasValue && checkProjectPath)) {/*Your Action*/}
}
If the purpose of the CheckProjectPath function is to validate a Path I cannot see any reason why the result should be bool?
Related
How does it work?
public class Node
{
Node Left ;
Node Right ;
}
...
var a = new Node();
var b = new Node();
if (a.Right == b.Right == null) // <- compiles and resharper says it's always false
{
}
var aa = 1;
var bb = 2;
if (aa == bb == 0) // doesn't compile Cannot apply operator '==' to operands of type 'bool' and 'int'
{
}
Why do multiple comparands work with 'Node' and doesn't work with 'Int'?
An expression like
a == b == c
is interpreted as
(a == b) == c
so first a == b is evaluated and returns either true or false, a boolean.
Then someBool == c is evaluated. If c is 0, then you are comparing a bool against an int, which leads to your compile error.
However if c is null, then both that null and that "someBool" are promoted lifted to a Nullable<bool> (or bool?), so they can be compared. But of course a true or false is never equal to (bool?)null, which is what Resharper says.
So you cannot take this shortcut and will have to write it as
(a == c) && (b == c)
Or in your case:
if (a.Right == null && b.Right == null) ...
if (aa == 0 && bb == 0) ...
In short, you can't compare like this, ever...
In regards to if (a.Right == b.Right == null)
It compiles because you can compare a non-nullable value types with null and it's always false.
a.Right == b.Right // bool
bool == null //will be lifted and always equal false (see below)
To know the reason why you'll have to visit the specs and understand lifted operators
12.4.8 Lifted operators
Lifted operators permit predefined and user-defined operators that
operate on non-nullable value types to also be used with nullable
forms of those types
For the equality operators == !=
a lifted form of an operator exists if the operand types are both
non-nullable value types and if the result type is bool. The lifted
form is constructed by adding a single ? modifier to each operand
type. The lifted operator considers two null values equal, and a null
value unequal to any non-null value. If both operands are non-null,
the lifted operator unwraps the operands and applies the underlying
operator to produce the bool result.
In regards to if(aa == bb == 0) you can't compare bool with an int, there is no implicit conversion to bool
aa == bb // bool
bool == 0 // there is no implicit conversion to bool
Why do multiple comparands work with 'Node' and doesn't work with
'Int'?
A) I guess you should be asking why it works with Null and not Int values. In your example above Node is a reference type and integer 0 is a value type. Read details below
All Value Types can be compared to null because they are convertible to nullable and null is the default value assigned to a Reference Types
Value types include : Bool, Integers, Floating points, char
Reference types include : Class, string, objects, interface
Valid Cases:
bool a =true;
if(a == null) //a is converted to a Nullable Boolean and then compared with null`
if(a.Right==b.Right==null) //First 2 statements are evaluated to boolean, which is converted to a Nullable Boolean and then compared with null`
int i=5;
if(i==null) // i is converted to a Nullable int and then compared with null, which always ends up false as the value of i is 5
Nullable<int> ii = 5;
if(ii==null) // ii being a nullable int is compared with null, there will not be any warnings indicated by the compiler as it know before hand that ii has a chance of being null
int a =5; int b=4;
if(a==b) // Valid, because your comparing 2 Integers are equal
Invalid Cases:
int a =5; int b=4;
if(a==b==0) // First 2 statements evaulate to a boolean and a boolean is evaluated to a Integer, the compiler fails to understand how to convert a Boolean to Int and hence the error
if(a==true) // same as above, compiler fails to compare an integer to a boolean and results in an error
To find true or false with a boolean nullable variable, I can use
bool? nullable;
bool non-nullable;
non-nullable = (nullable == true);
or
...
non-nullable = (nullable ?? false);
It appears that the result is the same either way:
nullable non-nullable result
-------- -------------------
true true
false false
null false
There certainly is a difference if these are integers, but I don't see any difference for this boolean example.
Is there any performance, or functional, difference between these?
For this boolean example, is there a reason to use one instead of the other?
Edit: fixed code - (nullable ?? true) should be (nullable ?? false)
There is yet another possible expression in your case:
non_nullable = nullable.HasValue && nullable.Value;
I don't exactly know if this will actually be slower than the other specified variants, since the operators on the nullable types are probably overloaded in the Nullable<T> structure as well and would involve method invocations as well. If you want to be sure about that, you will have to investigate and/or benchmark it.
As for the whole discussion about performance: I think it is better to first express your code as "naturally" as possible for future maintenance. Investigate performance improvements only when necessary. As Donald Knuth said: "Premature optimization is the root of all evil."
My advice about which expression to use would be to initially use the one that expresses your intent as clearly as possible. My personal choice would be: nullable == true.
== equality operator in C# and ?? is null-coalescing operator.
From MSDN site
The == (equality) and != (inequality) operators check if their
operands are equal or not.
The ?? operator is called the null-coalescing operator. It returns the
left-hand operand if the operand is not null; otherwise it returns the
right hand operand.
non-nullable = (nullable == true);
Above statements checks condition if nullable variable contains true then it assigns true value to non-nullable, otherwise assign false.
bool? nullable;
In your case you are creating nullable boolean type variable, it means it can store either bool value or null
non-nullable = (nullable ?? true);
In above statement, set non-nullable to the value of nullable if nullable is NOT null; otherwise, set it to true(which is provided as a constant or default value after ??).
nullable non-nullable result (nullable ?? true) why?
-------- ------------------- ------------------------
true true
false false
null false
(nullable == true) why? (replacing nullable with its value)
true == true, condition satisfies and returns true.
false == true, condition not satisfies and returns false, so non-nullable will be false.
null == true, condition not satisfies and returns false, so non-nullable will be false.
(nullable ?? false) why (nullable ?? true)
true?? false, it checks for value of nullable, it contains value i.e. true then it will assign that value to left hand side operand.
same as first point
null ?? false , now nullable variable contains null value, so it will assign false to left hand side operand
I have something like the following:
new ObservableCollection<SomeData>(SomeDataCollection.Where(a => a.AGD_Category.Equals((int)AGD_CategoryEnum.Med) && ((a.AGG_DateStart.Date <= SelectedUntill) && (a.AGG_DateEnd.Value.Date >= SelectedFrom))));
now my a.AGG_DateEnd is a nullable datetime and whenever there is a null value in the list I get an exception because of the "a.AGG_DateEnd.Value.Date" part.
But the thing is, the a.AGG_DateEnd also contains hours and minutes, but I do not want this causes my comparison to give unreliable results.
What can I do to improve?
Thank you,
A quick hack is:
a.AGG_DateEnd.GetValueOrDefault().Date >= SelectedFrom
This is OK because the default(DateTime) (which equals its own .Date) is not greater than any (other) DateTime value.
Otherwise the usual thing to do is:
a.AGG_DateEnd.HasValue && a.AGG_DateEnd.Value.Date >= SelectedFrom
where the double & ensures short-cut evaluation.
Addition after comments:
If you want the opposite answer in the case where it is null, it is:
(a.AGG_DateEnd ?? DateTime.MaxValue).Date >= SelectedFrom
respectively:
!a.AGG_DateEnd.HasValue || a.AGG_DateEnd.Value.Date >= SelectedFrom
Later edit: Since C# 6.0 (July 2015), you can use the ?. operator instead. So use the shorter code:
a.AGG_DateEnd?.Date >= SelectedFrom
which will (formally, at least) compare two nullable values of type DateTime?. When either operand is "null" (i.e. .HasValue gives false), such a comparison gives false.
If you want the opposite bool result in case of null, that is:
!(a.AGG_DateEnd?.Date < SelectedFrom)
Observe how x >= y is different from !(x < y) when we use these lifted operators that operate on Nullable<> values. Any lifted operator (like >= or <) will return false immediately if one of x and y is null; only if both x and y are non-null, will they be unwrapped and the contents compared with the non-lifted operator whose return value will be used.
I am trying to understand the difference between & and &&operators in C#. I searched on the internet without success. Can somebody please explain with an example?
& is the bitwise AND operator. For operands of integer types, it'll calculate the bitwise-AND of the operands and the result will be an integer type. For boolean operands, it'll compute the logical-and of operands. && is the logical AND operator and doesn't work on integer types. For boolean types, where both of them can be applied, the difference is in the "short-circuiting" property of &&. If the first operand of && evaluates to false, the second is not evaluated at all. This is not the case for &:
bool f() {
Console.WriteLine("f called");
return false;
}
bool g() {
Console.WriteLine("g called");
return false;
}
static void Main() {
bool result = f() && g(); // prints "f called"
Console.WriteLine("------");
result = f() & g(); // prints "f called" and "g called"
}
|| is similar to && in this property; it'll only evaluate the second operand if the first evaluates to false.
Of course, user defined types can overload these operators making them do anything they want.
Strongly recommend this article from Dotnet Mob : http://codaffection.com/csharp-article/short-circuit-evaluation-in-c/
-&& is short-circuit logical operator
For AND operations if any of the operand evaluated to false then total expression evaluated to false, so there is no need to evaluate remaining expressions, similarly in OR operation if any of the operand evaluated to true then remaining evaluation can be skipped
-& operator can be used as either unary or binary operator. that is, unary & can be used to get address of it’s operand in unsafe context.
& can be used on either integral types (like int, long etc.) or on bool.
When used on an integral type, it performs a bitwise AND and gives you the result of that. When used on a bool, it performs a logical AND on BOTH its operands and gives you the result.
&& is not used as a bitwise AND. It is used as a logical AND, but it does not necessarily check both its operands. If the left operand evaluates to false, then it doesn't check the right operand.
Example where this matters:
void Action()
{
string name = null;
if(name != null && name.EndsWith("ack"))
{
SomeOtherAction();
}
}
If name is null, then name.EndsWith("ack") will never get executed. It is smart enough to know if the left operand is false, then the right operand doesn't need to be evaluated (aka "short-circuiting"). That's good because calling a method on null will throw a NullReferenceException.
If you changed it into if(name != null & name.EndsWith("ack")), both sides would get evaluated and it would throw a NullReferenceException.
One detail: & can also be a unary operator (so it has one operand) in an unsafe context. It will give the address of a value or object. It's not important though, as most people don't ever have to touch this part of the language.
Below example and explanation's may help.
Example:
public static bool Condition1()
{
Console.WriteLine("Condition1 is evaluated.");
return false;
}
public static bool Condition2()
{
Console.WriteLine("Condition2 is evaluated.");
return true;
}
1. Logical Operator
& (ampersand) Logical AND operator
| (pipeline) Logical OR operator
Used for ensuring all operands are evaluated.
if(Condition1() & Condition2())
{
Console.WriteLine("This will not print");
//because if any one operand evaluated to false ,
//thus total expression evaluated to false , but both are operand are evaluated.
}
if (Condition2() | Condition1())
{
Console.WriteLine("This will print");
//because any one operand evaluated to true ,
//thus total expression evaluated to true , but both are operand are evaluated.
}
2. Conditional Short Circuit Operator
&& (double ampersand) Conditional AND operator
|| (double pipeline) Conditional OR operator
Used for Skipping the right side operands , Has Side effects so use carefully
if (Condition1() && Condition2())
{
Console.WriteLine("This will not print");
//because if any one operand evaluated to false,
//thus total expression evaluated to false ,
//and here the side effect is that second operand is skipped
//because first operand evaluates to false.
}
if (Condition2() || Condition1())
{
Console.WriteLine("This will print");
//because any one operand evaluated to true
//thus remaining operand evaluations can be skipped.
}
Note:
To get better understanding test it in console sample.
References
dotnetmob.com
wikipedia.org
stackoverflow.com
& is a bitwise operator and && is a logical operator that applies to bool operands.
Easy way to look it is logical & will evaluate both sides of the & regardless if the left side is false, whereas the short-circuit && will only evaluate the right side if the left is true.
d=0;
n=10;
// this throws divide by 0 exception because it evaluates the
// mod even though "d != 0" is false
if ( (d != 0) & (n % d) == 0 )
Console.Writeline( d + " is a factor of " + n);
// This will not evaluate the mod.
if ( (d != 0) && (n % d) == 0 )
Console.Writeline( d + " is a factor of " + n);
The first one is bitwise and the second one is boolean and.
According to - C# 4.0 The Complete Reference by Herbert Schildt
& - Logical AND Operator
| - Logical OR Operator
&& - Short Circuited AND Operator
|| - Short Circuited OR Operator
A simple example can help understand the phenomena
using System;
class SCops {
static void Main() {
int n, d;
n = 10;
d = 2;
if(d != 0 && (n % d) == 0)
Console.WriteLine(d + " is a factor of " + n);
d = 0; // now, set d to zero
// Since d is zero, the second operand is not evaluated.
if(d != 0 && (n % d) == 0)
Console.WriteLine(d + " is a factor of " + n);
// Now, try the same thing without the short-circuit operator.
// This will cause a divide-by-zero error.
if(d != 0 & (n % d) == 0)
Console.WriteLine(d + " is a factor of " + n);
}
}
Here the & operator checks each and every operand and && checks only the first operand.
As you might notice for 'AND' operations any operand which is false will evaluate the whole expression to false irrespective of any other operands value in the expression.
This short circuited form helps evaluate the first part and is smart enough to know if the second part will be necessary.
Running the program will throw a divide-by-zero error for the last if condition where both the operands are checked for & operator and no exception handling is done to tackle the fact that 'd' can be 0 at any point of time.
The same case applies to '|' in C#.
This is slightly different than C or C++ where '&' and '|' were bitwise AND and OR operators. However C# also applies the bitwise nature of & and | for int variables only.
Hai Friend,
The Operator &&(Logical Operator) is used in conditional statements.
For Instance
if(firstName == 'Tilsan' && lastName == 'Fighter')
{
Response.Write("Welcome Tilsan The Fighter!");
}
the Response.Write statement will run only if both variables firstName and lastName match to their condition.
Whereas & (Bitwise Operator)operator is used for Binary AND operations, i.e., if we write:
bool a, b, c;
a = true;
b = false;
c = a & b;
Response.Write(c); // 'False' will be written to the web page
Here first Binary And operation will be performed on variables a and b, and the resultant value will be stored in variable c.
In C#, for example, when I compare two nullable booleans (bool?) I get the following results :
true & null = null
false & null = false
true | null = true
false | null = null
The issue is that I couldn't understand how those results come, what's the rule which I can use to determine the result of a logical operator on two booleans, when one of them is null?
The idea is that "null" means "unknown" here, or "not enough information". So if the answer depends on the unknown value, the answer itself is unknown. If the answer will be the same whatever the unknown value is (e.g. true | null) then you're still okay.
Think of it this way:
y = true & x; // the result will be the same as the value of x (it depends on x)
y = true | x; // the result will be true whatever x is