-2

I'm trying to translate a Javascript function to C# when I encountered something I've never seen before:

return (a / (b - (c * G * (d || 0)))) || 0;

C# is complaining about the d || 0 portion being applied to floating point number, and I have no idea what that Javascript operator does. (in C#, it's a logical OR)

Edit: all variables are floating point numbers.

3 Answers3

2

The || operator returns the expression on the left side if that expression is truthy, otherwise it returns the expression on the right side. It's commonly used like this to specify default/fallback values, for instance, when a number is expected but the provided variable might contain undefined or null. It's also commonly used when optional arguments can be passed to a function and the function want's to simply use the first one that's truthy.

Lennholm
  • 7,205
  • 1
  • 21
  • 30
  • 5
    null coalescing operator--C# equivalent is ?? – bdimag Jul 10 '17 at 19:35
  • 1
    so in other words, if the left side is "true" (non-zero) that's the result, otherwise zero is the result? if so then that seems a bit redundant... – William Scott Jul 10 '17 at 19:40
  • This is only half an answer (what it is, not the c# equivalent) – Camilo Terevinto Jul 10 '17 at 19:41
  • 1
    @bdimag It's not directly equivalent though since `null` is not equivalent to Javascripts concept of "falsy" values, so you need to consider this when translating code like from JS to C# – Lennholm Jul 10 '17 at 19:41
  • @WilliamScott there is a difference between true and truthy – charlietfl Jul 10 '17 at 19:42
  • 2
    @AlexanderDerck That's incorrect, negative numbers are truthy, only 0 is falsy – Lennholm Jul 10 '17 at 19:43
  • 1
    @WilliamScott It's commonly used because there's no guarantee that the variable is a number, so it's basically a method to convert any instances of `undefined`, `null`, etc. to `0` – Lennholm Jul 10 '17 at 19:45
  • OK, thank you everyone... now it makes sense, and it is redundant when used in C# – William Scott Jul 10 '17 at 19:46
  • @MikaelLennholm correct, not exactly the same, although given his example, I'm sure that's how it was being used (`d` or if undefined/null then `0`). Less useful for working with numbers in C#, when you'd get compile errors for unset variables and unset properties of types like `int`, would already be `0`. – bdimag Jul 10 '17 at 19:59
1

|| is the "short-circuited" OR operator and in order for it to work, both operands must first be evaluated as Booleans. From left to right, the value of the first expression that can be converted to true is returned (the original value, not the converted Boolean).

JavaScript will perform an implicit conversion to determine the "truthiness" of each operand if necessary, but C# will not. A float in C# is invalid with this operator because C# is a strongly-typed language and implicit conversions do not occur. You would have to explicitly cast your float to a Boolean to be able to use this operator in C#.

In C#, you'd need:

((bool) d || 0)
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • it is, but not in this context – bdimag Jul 10 '17 at 19:37
  • @bdimag It certainly is. – Scott Marcus Jul 10 '17 at 19:37
  • You mean, "... in order for it to work **in C#**", right? – Pointy Jul 10 '17 at 19:39
  • Not at all. See here: https://stackoverflow.com/a/3088161/3932049 – Camilo Terevinto Jul 10 '17 at 19:40
  • @CamiloTerevinto a floating point value **in C#** is not a valid operand. In this answer he's talking about C#, where the error in the OP is happening, not JavaScript. – Pointy Jul 10 '17 at 19:41
  • @CamiloTerevinto What are you talking about? – Scott Marcus Jul 10 '17 at 19:41
  • "I'm trying to translate a Javascript function"... – Camilo Terevinto Jul 10 '17 at 19:41
  • @CamiloTerevinto right, but the error is coming from C#, where a number is not a valid operand for the `||` operator. Basically the "translation" so far has involved pasting the JavaScript code directly into C# code and trying to compile it. – Pointy Jul 10 '17 at 19:42
  • I understand that, but the OP is saying "and I have no idea what that Javascript operator does" so it'd make sense to explain the difference – Camilo Terevinto Jul 10 '17 at 19:43
  • @CamiloTerevinto Yes, *translate* it into C#. So, I've explained what is happening in JavaScript and why it doesn't work in C#. I've answered the OPs question about why he is getting the error. – Scott Marcus Jul 10 '17 at 19:43
  • 1
    I agree that the answer could use some elaboration. The operator does a similar thing in both languages, but there are very important differences. – Pointy Jul 10 '17 at 19:43
  • I am really at a loss here. My original answer clearly explained that `||` requires boolean operands and that JavaScript converts the float to a boolean automaticaly and that C# doesn't. What is the confusion here? – Scott Marcus Jul 10 '17 at 19:46
  • @Pointy *"You mean, "... in order for it to work in C#", right?"* No, I don't. It works the same way in both languages (short-circuited logical OR). The difference in the languages is not about the functionality of `||`, it's about the operands being implicitly converted to Booleans by JavaScript and not by the .NET CLR. – Scott Marcus Jul 10 '17 at 19:50
  • 1
    @ScottMarcus Eh, `||` in JS does NOT require the operands to be boolean and it doesn't convert them. `1 || 2` will return `1`, `null || 2` will return `2`, and so on. – Lennholm Jul 10 '17 at 19:54
  • While it's true that the *evaluation* of `||` ultimately requires boolean operands, in the actual source expression the operands can be of *any* type, and the *result* of `||` depends on the type of the operand that "wins" the test. (Which I'm sure you know; I'm just explaining why the answer seems to have confused people.) (or guessing at an explanation) – Pointy Jul 10 '17 at 19:58
  • 1
    @Pointy Have I not clearly stated this (over and over at this point)? *"JavaScript will perform an implicit conversion if necessary, C# will not."* – Scott Marcus Jul 10 '17 at 19:59
  • @ScottMarcus Yes yes, **I** understand what you're saying, but that way of stating the issue seems to be a little subtle. – Pointy Jul 10 '17 at 20:00
  • 1
    @MikaelLennholm From [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators): *"Returns expr1 if it can be **converted** to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true."* – Scott Marcus Jul 10 '17 at 20:01
  • @MikaelLennholm You misunderstand me (and I'ved edited the answer to be clearer). I meant that they are converted to Booleans (which does, in fact happen). The reason that `null || 2` returns `2` is because `null` is first converted to a Boolean and given that `null` is "falsely", it converts to `false`. And, `1 || 2` returns `1` because `1` is "truthy" and when converted to a Boolean, converts to `true`. – Scott Marcus Jul 10 '17 at 20:04
  • @ScottMarcus **can be converted** and **is implicitly converted** are two different statements, the latter implying that the converted value is what gets returned. "*Return expr1 if it **can be** converted to true*" is just a formal and convoluted way of saying "*Return expr1 if it's truthy*". You're arguing semantics. – Lennholm Jul 10 '17 at 20:07
  • 1
    @MikaelLennholm I think you are arguing semantics. If the JS runtime attempts a conversion without user intervention, then that is the very definition of "implicit". The operand **is** implicitly converted to a Boolean. The user agent is directed to convert it to `true` when the value is "truthy" and `false` when the value is "falsely". I never once commented on what gets returned. I really don't understand your argument here. The docs are pretty clear here. – Scott Marcus Jul 10 '17 at 20:13
  • @MikaelLennholm The phrase that probably should be used is `coercively equal to true`. The definition of `coercively equal`, however, is precisely what MDN states, which is that a value can be converted to true (AKA "truthy"). – mhodges Jul 10 '17 at 20:52
  • @MikaelLennholm Also, the JS engine does not know if it **can be converted** to truthy without actually trying it, so the two are the same. If you read the actual [`ECMAScript specification`](http://www.ecma-international.org/ecma-262/6.0/#sec-binary-logical-operators-runtime-semantics-evaluation), it walks you through the flow of events/comparisons that happen in order to determine truthy/falsey. – mhodges Jul 10 '17 at 20:55
0

|| (OR)operator works when both the operands are Boolean. If not then JavaScript tries to implicitly convert it and perform the OR operation.

You need to explicitly cast in C#.

Sampath
  • 14
  • 2