It is not quite as simple. The C# language doesn't model a NAND gate at all with the && operator. That operator has short-circuiting behavior, very convenient in a C# program. And common behavior for the curly-brace languages, an expression like this doesn't crash your code:
arr[] = somefunction();
int ix = foo;
if (ix < arr.Length && arr[ix] == 42) {
EmailBookRecommendation();
}
But that's a very inefficient version of the expression, this one is way more performant:
if (ix < arr.Length & arr [ix] == 42)
Which is a perfectly legal expression, the & operator works just fine with boolean operands. But unfortunately this one crashes your code. It evaluates the array indexing expression and that goes Kaboom! with IndexOutOfRangeException.
That's not ever a problem with a NAND gate, it doesn't crash when the first input is F :) There are many possible C# expressions where that's not a problem. You really should favor the & operator for those. It makes a huge difference. So always write something like this:
if (ix >= 1 & ix <= 42)
Which of course can never fail. To understand why the && operator is so much more inefficient than the & operator, you have to understand branch prediction. That's covered very well in this answer.