Mike.Sheen wrote:pricerc wrote:"And" and "AndAlso" are just VB's version of "&" and "&&"
Not quite... & in C# is bitwise and && is logical.
In respect to C#'s && - the C# compiler will short circuit the evaluation of a logical expression automatically. The same with C#'s Or operator (||).
VB's logical And operator does no short-circuit, so AndAlso and OrElse were introduced which do short-circuit the evaluation to match C# in that feature.
I don't know why they didn't just make VB's And and Or short-circuit all the time and not need to introduce new operators - probably a very simple obvious reason which I'm just overlooking right now.
I know all that; I just didn't think this was the right thread for a big VB vs. C# discussion, which is why I generalised it down to " C#'s equivalents are not *exactly* the same ".
But since you started
...
1) The main reason for not making "And" and "Or" short-circuit is simple: Backward-compatibility. Despite it always being a bad idea, people had code that depended on the not-short-circuiting 'feature'.
2) A second important reason is that "And" and "Or" are actually *bit-wise* operators, not logical operators. Their legacy use as boolean operators (what most people think of them as) is possible because in VB, False = Zero and True = Anything-But-Zero (kind of like C/C++). So if they didn't add new keywords for the short-circuits, then they would have needed to add new keywords for the bit-wise versions. They went with the version with no breaking changes and opt-in for the short-circuit functionality.
A comparison; if you don't already have it, grab a copy of LinqPad (
https://www.linqpad.net/) to run these. As an aside, the VB code is about 40 fewer characters, even with the words (half of which the editor types) instead of squiggly brackets.
- Code: Select all
<Flags>
Enum Foo
None = 0
Bar1 = 1
Bar2 = 2
Bar4 = 4
BarAll = Bar1 Or Bar2 Or Bar4
End Enum
Sub Main
Dim fu As Foo = Foo.Bar1 Or Foo.Bar2
TestFoo(fu, Foo.Bar2, Foo.Bar4)
TestFoo(fu, Foo.Bar2, Foo.BarAll)
End Sub
Sub TestFoo(fu As Foo, testFu As Foo, testFu2 As Foo)
Dim fuTest1 = fu And testFu
fuTest1.Dump("fuTest1")
Dim fuTest2 = fu AndAlso testFu
fuTest2.Dump("fuTest2")
Dim fuTest3 = (fu And testFu) = testFu2
fuTest3.Dump("fuTest3")
Dim fuTest4 = (fu And testFu) And testFu2
fuTest4.Dump("fuTest4")
Dim fuTest5 = (fu And (testFu Or testFu2))
fuTest5.Dump("fuTest5")
Dim fuTest6 = (fu And testFu) OrElse (fu And testFu2)
fuTest6.Dump("fuTest6")
End Sub
- Code: Select all
[FlagsAttribute]
enum Foo {
None = 0,
Bar1 = 1,
Bar2 = 2,
Bar4 = 4,
BarAll = Bar1 | Bar2 | Bar4
}
void Main()
{
var fu = Foo.Bar1 | Foo.Bar4;
TestFoo(fu, Foo.Bar2, Foo.Bar4);
TestFoo(fu, Foo.Bar2, Foo.BarAll);
}
void TestFoo(Foo fu, Foo testFu, Foo testFu2) {
var fuTest1 = (fu & testFu);
fuTest1.Dump("fuTest1");
var fuTest2 = (fu != Foo.None) && (testFu != Foo.None);
fuTest2.Dump("fuTest2");
var fuTest3 = ((fu & testFu) == testFu2);
fuTest3.Dump("fuTest3");
var fuTest4 = ((fu & testFu) & testFu2);
fuTest4.Dump("fuTest4");
var fuTest5 = (fu & (testFu | testFu2));
fuTest5.Dump("fuTest5");
var fuTest6 = ((fu & testFu) != Foo.None) || ((fu & testFu2) != Foo.None);
fuTest6.Dump("fuTest6");
}