Search Unity

what does "?" mean?

Discussion in 'Scripting' started by lucky devil, Jan 25, 2012.

  1. lucky devil

    lucky devil

    Joined:
    Sep 13, 2010
    Posts:
    13
    recently i have been reading a tutorial book and came across a question mark in the script and wondered what it did the script stops working when i take it out but works when it's in
    here is where it occurs

    any idea of what it does is better than what I know at the moment
     
  2. Marrrk

    Marrrk

    Joined:
    Mar 21, 2011
    Posts:
    1,032
    Its a http://en.wikipedia.org/wiki/Ternary_operation, you could write this statement like this:

    Code (csharp):
    1.  
    2. if (Input.GetAxis("Horizontal") <0)
    3.   in_direction =  -1;                  
    4. else
    5.   in_direction =  1;                   
    6.  
     
    Vasileios_P likes this.
  3. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    if Input.GetAxis("Horizontal")<0 then in_direction = -1 else in_direction = 1
     
  4. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    It is a short hand for writing an if statement. That code is equivalent to:
    Code (csharp):
    1. if (Input.GetAxis("Horizontal")  < 0) in_direction = -1 else in_direction = 1;
    Edit: haha, 3 identical replies in under a minute :p
     
    Vasileios_P likes this.
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Got to advise against this behaviour, all it really does is lead to bugs. Keep the code clean, people. It isn't faster to execute on mono.
     
  6. burnumd

    burnumd

    Joined:
    May 27, 2008
    Posts:
    367
    It's the conditional operator. Full documentation on it can be found here. In short, it evaluates whatever is to the left of the question mark, which in this case is
    Code (csharp):
    1. Input.GetAxis ("Horizontal") < 0
    So if that's true (eg, the player is holding left on the keyboard/joystick), the resulting value is what's immediately to the right of the question mark (in this case, -1). Otherwise (player input is neutral or to the right), it's whatever's to the right of the colon (or 1, in your example). It would probably be clearer if the code was spaced a little differently, but that's the gist of what it does. You can also chain them together, so if, for example, you wanted to exclude the neutral input case, you could do:
    Code (csharp):
    1. Input.GetAxis ("Horizontal") < 0 ? -1 : (Input.GetAxis ("Horizontal") > 0 ? 1 : 0)
     
    Vasileios_P likes this.
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    The usage of it alone doesn't lead to bugs, however any bugs that arise out of it are more difficult to debug because you can't step through it like you can an if-else block.

    While I wouldn't typically use it for something like this, I will use it periodically in a get for boolean properties.
     
  8. ptdnet

    ptdnet

    Joined:
    Apr 20, 2011
    Posts:
    100
    Um, no.
     
  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah, actually. I'll say it in a way you can understand:

    Usage of this makes your code piss poor to read. Happy?
     
    Vasileios_P likes this.
  10. siflandolly

    siflandolly

    Joined:
    May 17, 2011
    Posts:
    141
    It can be useful for checking for nulls in a concise way:

    string Firstname = person["First Name"] != null ? person["First Name"].ToString() : String.Empty;
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Actually it is slightly faster in some cases (not enough to be worth caring about though). Also, in some cases I do consider the code to be cleaner, such as when declaring variables. e.g.,

    Code (csharp):
    1. var foo = 5;
    2. if (something > 42) {
    3.     foo = 8;
    4. }
    compared to

    Code (csharp):
    1. var foo = (something > 42)? 8 : 5;
    I also use it when the alternative involves cumbersome repetition of code:

    Code (csharp):
    1. if (something) {
    2.     blah = AComplicatedFunction (12, Vector3.zero, foo, 85, theKitchenSink, true);
    3. }
    4. else {
    5.     blah = AComplicatedFunction (12, Vector3.zero, foo, 85, theKitchenSink, false);
    6. }
    compared to

    Code (csharp):
    1. blah = AComplicatedFunction (12, Vector3.zero, foo, 85, theKitchenSink, something? true : false);
    Especially in cases like this, where the focus should be on assigning the result of AComplicatedFunction to "blah", not using the ternary operator changes it to a whole ordeal about checking "something", which is really just one parameter out of several, plus checking "something" becomes physically separated from the results, so you have to scan multiple lines and play "spot the difference" to figure out what's going on.

    Otherwise, I would agree that using it to make cute one-line statements for the sake of it is a bad idea. Like the example above,

    Code (csharp):
    1. Input.GetAxis ("Horizontal") < 0 ? -1 : (Input.GetAxis ("Horizontal") > 0 ? 1 : 0)
    I would definitely consider that obfuscated.

    --Eric
     
  12. Marrrk

    Marrrk

    Joined:
    Mar 21, 2011
    Posts:
    1,032
    Try this:

    Code (csharp):
    1.  
    2. var Firstname =  person["First Name"] ?? string.Empty;
    3.  
    Only works when person["bla"] returns the same type as the right value though.
     
  13. siflandolly

    siflandolly

    Joined:
    May 17, 2011
    Posts:
    141

    Interesting...what does ?? do
     
  14. Paulo-Henrique025

    Paulo-Henrique025

    Joined:
    Dec 12, 2010
    Posts:
    230
    Man this thread is so much fun

    I have nothing to add, just saying you guys are giving me laughs.
     
  15. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    I prefer it as opposed to a full on if else block. Much cleaner IMO, and not that much harder to read unless you're an amateur.

    Nested ones can get tricky to read tho...

    myvalue = value > 5 ? 1 : value > 10 ? 2 : 0;
     
  16. Giometric

    Giometric

    Joined:
    Dec 20, 2011
    Posts:
    170
    The ?? returns what's to the left of it, if that isn't null, or what's on the right otherwise.

    So, if person["First Name"] returned a valid string, Firstname would be set to whatever person["First Name"] would evaluate to. Otherwise, it would end up being set to string.Empty. It's a little bit like the ? one that was discussed above except that it is specifically checking for null.

    Another way to write it is:

    Code (csharp):
    1.  
    2. var Firstname;
    3.  
    4. if (person["First Name"] != null) {
    5.      Firstname = person["First Name"];
    6. }
    7. else {
    8.      Firstname = string.Empty;
    9. }
    10.  
     
  17. siflandolly

    siflandolly

    Joined:
    May 17, 2011
    Posts:
    141

    Thanks!
     
  18. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    The Docs for "??": http://msdn.microsoft.com/en-us/library/ms173224.aspx
    Very handy for nullable types, also nice shorthand syntax for reference types.

    Edit:
    Also, I prefer the ternary operator over if-else for legibility when it's simple assignations(with the same reasoning as Eric5h5), rather than more complex logic. The problem of debugging arises when people do stupid messes like this:
    Code (csharp):
    1.  
    2. int a = b ?? c ? d : e ? f ? g : h : i;
    3.  
    That kinda of coding should be taken out back and shot. Though there is nothing difficult to read or debug from a simple use of ternary operator.

    There is also a slight performance boost, as it's sometimes called the 'Branch-less Conditional', but only under some conditions(e.g. don't call functions with it). Though it's a very micro-optimization, so 99.9%+ of the time you don't choose it for it's speed.
     
    Last edited: Jan 25, 2012
  19. lucky devil

    lucky devil

    Joined:
    Sep 13, 2010
    Posts:
    13
    that has cleared lots up thanks for the detail as well everyone :)

    and one more what does "!" do it comes up sometimes
     
    Last edited: Jan 25, 2012
  20. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Not.

    Code (csharp):
    1.  
    2. bool thing;
    3.  
    4. // if thing is true
    5. if (thing) {...}
    6.  
    7. // if thing is false (or 'NOT' true)
    8. if (!thing) {...}
    9.