Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. How well do you know your TryParse()?

How well do you know your TryParse()?

Scheduled Pinned Locked Moved C#
csharpcomtoolsquestion
22 Posts 7 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Alan N

    Well, ok I have peeked to see if the behaviour is the same as Int32.TryParse and it is. Importantly the out keyword requires that the variable passed as the argument is definitely assigned by the method and whether the method returns true or false has no bearing on that requirement. So my answer is I would expect foo to be assigned but whether or not that changes the value depends on whether the method assigns MinValue or something else. Alan.

    RaviBeeR Offline
    RaviBeeR Offline
    RaviBee
    wrote on last edited by
    #3

    Alan N wrote:

    the out keyword requires that the variable passed as the argument is definitely assigned by the method

    Yes, absolutely.  And I was hoping TryParse() would assign the incoming value of foo when the parse failed.  When it failed to do so, I decided to write my own SafeTryParse() implementation that would do just that, only to be chastised by the compiler - an out parameter is always assumed to be uninitialized and therefore its value can't be used. :) /ravi

    My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

    A 1 Reply Last reply
    0
    • RaviBeeR RaviBee

      Alan N wrote:

      the out keyword requires that the variable passed as the argument is definitely assigned by the method

      Yes, absolutely.  And I was hoping TryParse() would assign the incoming value of foo when the parse failed.  When it failed to do so, I decided to write my own SafeTryParse() implementation that would do just that, only to be chastised by the compiler - an out parameter is always assumed to be uninitialized and therefore its value can't be used. :) /ravi

      My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

      A Offline
      A Offline
      Alan N
      wrote on last edited by
      #4

      I did that test, only to get my wrist slapped too! Alan.

      RaviBeeR 1 Reply Last reply
      0
      • A Alan N

        I did that test, only to get my wrist slapped too! Alan.

        RaviBeeR Offline
        RaviBeeR Offline
        RaviBee
        wrote on last edited by
        #5

        Heh.  So this is what I ended up creating:

        public void SafeTryParse
        (string stringValue,
        Decimal? defaultValue,
        out Decimal value)
        {
        if (!Decimal.TryParse (stringValue, out value) && defaultValue.HasValue) {
        value = defaultValue.Value;
        }
        }

        /ravi

        My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

        A 1 Reply Last reply
        0
        • RaviBeeR RaviBee

          Heh.  So this is what I ended up creating:

          public void SafeTryParse
          (string stringValue,
          Decimal? defaultValue,
          out Decimal value)
          {
          if (!Decimal.TryParse (stringValue, out value) && defaultValue.HasValue) {
          value = defaultValue.Value;
          }
          }

          /ravi

          My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

          A Offline
          A Offline
          Alan N
          wrote on last edited by
          #6

          Or change out to ref and do this:

          private bool SafeTryParse(string s, ref decimal result) {
            decimal temp;
            bool ok = Decimal.TryParse(s, out temp);
            if (ok) result = temp;
            return ok;
          }
          

          Alan

          RaviBeeR L 2 Replies Last reply
          0
          • A Alan N

            Or change out to ref and do this:

            private bool SafeTryParse(string s, ref decimal result) {
              decimal temp;
              bool ok = Decimal.TryParse(s, out temp);
              if (ok) result = temp;
              return ok;
            }
            

            Alan

            RaviBeeR Offline
            RaviBeeR Offline
            RaviBee
            wrote on last edited by
            #7

            Great minds think alike. :) /ravi

            My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

            1 Reply Last reply
            0
            • A Alan N

              Or change out to ref and do this:

              private bool SafeTryParse(string s, ref decimal result) {
                decimal temp;
                bool ok = Decimal.TryParse(s, out temp);
                if (ok) result = temp;
                return ok;
              }
              

              Alan

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #8

              Hmm. That isn't very safe, result could contain an unintended value:

              decimal val;
              // now first use of val, not meant to provide the default value
              val=some_garbage;
              someOperations(val);
              // now second use, forgetting to set the actual default value
              bool OK=SafeTryParse("foo", ref val);
              // val still contains garbage

              One shouldn't give two roles to a single variable, so I'd rather have two overloads both using the out keyword:

              // result is zero when parse fails
              private bool SafeTryParse(string s, out decimal result);

              // result is dflt when parse fails
              private bool SafeTryParse(string s, out decimal result, decimal dflt);

              You can still get the "overwrite when parse succeeds" effect by passing val twice to the latter. :)

              Luc Pattyn [My Articles] Nil Volentibus Arduum

              RaviBeeR 1 Reply Last reply
              0
              • L Luc Pattyn

                Hmm. That isn't very safe, result could contain an unintended value:

                decimal val;
                // now first use of val, not meant to provide the default value
                val=some_garbage;
                someOperations(val);
                // now second use, forgetting to set the actual default value
                bool OK=SafeTryParse("foo", ref val);
                // val still contains garbage

                One shouldn't give two roles to a single variable, so I'd rather have two overloads both using the out keyword:

                // result is zero when parse fails
                private bool SafeTryParse(string s, out decimal result);

                // result is dflt when parse fails
                private bool SafeTryParse(string s, out decimal result, decimal dflt);

                You can still get the "overwrite when parse succeeds" effect by passing val twice to the latter. :)

                Luc Pattyn [My Articles] Nil Volentibus Arduum

                RaviBeeR Offline
                RaviBeeR Offline
                RaviBee
                wrote on last edited by
                #9

                I would argue that forgetting to set a valid initial value is programmer error, however I now like the idea of an explicit default.  That's what I initially implemented (link[^]), but like Alan, switched to the 2 parameter ref version.  I'm going to switch back. Thanks, /ravi

                My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                P 1 Reply Last reply
                0
                • RaviBeeR RaviBee

                  What would you expect foo to be after this code fragment runs?  Post your answer without first peeking at the docs! :-D

                  string badNumericString = "Bogus";
                  Decimal foo = Decimal.MinValue;
                  bool status = Decimal.TryParse (badNumericString, out foo); // status is false, as expected

                  Answer:

                  • Decimal.MinValue (since the parse failed)
                  • Something else (if so, what?)

                  /ravi

                  My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                  P Offline
                  P Offline
                  PIEBALDconsult
                  wrote on last edited by
                  #10

                  Well it's zero, right?

                  L L RaviBeeR 3 Replies Last reply
                  0
                  • P PIEBALDconsult

                    Well it's zero, right?

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #11

                    Do we actually care, if the value isn't being used?

                    string badNumericString = "Bogus";
                    Decimal foo; // will be initialized to 0 by the runtime
                    if (!Decimal.TryParse (badNumericString, out foo)) foo = 1; // default value here

                    ..and if the TryParse don't use the value, it'll probably initialize it with the same value it initializes an empty variable. Since the variable hasn't been set (according to application logic), we can't be sure about the value unless we explicitly set it. (Future versions of .NET might display other behavior)

                    Bastard Programmer from Hell :suss:

                    D P RaviBeeR 3 Replies Last reply
                    0
                    • L Lost User

                      Do we actually care, if the value isn't being used?

                      string badNumericString = "Bogus";
                      Decimal foo; // will be initialized to 0 by the runtime
                      if (!Decimal.TryParse (badNumericString, out foo)) foo = 1; // default value here

                      ..and if the TryParse don't use the value, it'll probably initialize it with the same value it initializes an empty variable. Since the variable hasn't been set (according to application logic), we can't be sure about the value unless we explicitly set it. (Future versions of .NET might display other behavior)

                      Bastard Programmer from Hell :suss:

                      D Offline
                      D Offline
                      DaveyM69
                      wrote on last edited by
                      #12

                      Eddy Vluggen wrote:

                      it'll probably initialize it with the same value it initializes an empty variable

                      Double checked using Reflector...

                      public static bool TryParse(string s, out decimal result)
                      {
                      return Number.TryParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo, out result);
                      }

                      internal static unsafe bool TryParseDecimal(string value, NumberStyles options, NumberFormatInfo numfmt, out decimal result)
                      {
                      byte* stackBuffer = stackalloc byte[0x72];
                      NumberBuffer number = new NumberBuffer(stackBuffer);
                      result = 0M; // result is set to zero here!
                      if (!TryStringToNumber(value, options, ref number, numfmt, true))
                      {
                      return false;
                      }
                      if (!NumberBufferToDecimal(number.PackForNative(), ref result))
                      {
                      return false;
                      }
                      return true;
                      }

                      ... so it WILL be zero.

                      Dave
                      Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
                      BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                      1 Reply Last reply
                      0
                      • P PIEBALDconsult

                        Well it's zero, right?

                        L Offline
                        L Offline
                        Luc Pattyn
                        wrote on last edited by
                        #13

                        That is what the doc[^] says. This entire thread seams to suggest no-one reads or beliefs it. :)

                        Luc Pattyn [My Articles] Nil Volentibus Arduum

                        P RaviBeeR 2 Replies Last reply
                        0
                        • L Luc Pattyn

                          That is what the doc[^] says. This entire thread seams to suggest no-one reads or beliefs it. :)

                          Luc Pattyn [My Articles] Nil Volentibus Arduum

                          P Offline
                          P Offline
                          PIEBALDconsult
                          wrote on last edited by
                          #14

                          Luc Pattyn wrote:

                          no-one reads or beliefs it

                          Maybe I'm a one-percenter. :-D My understanding is that all TryParse methods are expected to set the value to zero/null/default(T) when they fail -- so that's what I do when I write a Tryxxx method.

                              public bool
                              TryParse
                              (
                                  string Name
                              ,
                                  out T  Value
                              )
                              {
                                  bool result = true ;
                          
                                  Value = default(T) ;
                          

                          public static bool
                          TryGetValue<T>
                          (
                          this object Source
                          ,
                          out T Value
                          )
                          {
                          bool result = false ;

                          Value = default(T) ;

                          L 1 Reply Last reply
                          0
                          • RaviBeeR RaviBee

                            I would argue that forgetting to set a valid initial value is programmer error, however I now like the idea of an explicit default.  That's what I initially implemented (link[^]), but like Alan, switched to the 2 parameter ref version.  I'm going to switch back. Thanks, /ravi

                            My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                            P Offline
                            P Offline
                            PIEBALDconsult
                            wrote on last edited by
                            #15

                            Then I prefer to provide a value; something like this:

                                public virtual T
                                ExecuteScalar<T>
                                (
                                    T IfNull
                                )
                                {
                            

                            you could do similar for TryParse.

                            1 Reply Last reply
                            0
                            • L Lost User

                              Do we actually care, if the value isn't being used?

                              string badNumericString = "Bogus";
                              Decimal foo; // will be initialized to 0 by the runtime
                              if (!Decimal.TryParse (badNumericString, out foo)) foo = 1; // default value here

                              ..and if the TryParse don't use the value, it'll probably initialize it with the same value it initializes an empty variable. Since the variable hasn't been set (according to application logic), we can't be sure about the value unless we explicitly set it. (Future versions of .NET might display other behavior)

                              Bastard Programmer from Hell :suss:

                              P Offline
                              P Offline
                              PIEBALDconsult
                              wrote on last edited by
                              #16

                              Eddy Vluggen wrote:

                              Do we actually care

                              Not particularly, but we care whether or not it does what the documentation says.

                              1 Reply Last reply
                              0
                              • P PIEBALDconsult

                                Luc Pattyn wrote:

                                no-one reads or beliefs it

                                Maybe I'm a one-percenter. :-D My understanding is that all TryParse methods are expected to set the value to zero/null/default(T) when they fail -- so that's what I do when I write a Tryxxx method.

                                    public bool
                                    TryParse
                                    (
                                        string Name
                                    ,
                                        out T  Value
                                    )
                                    {
                                        bool result = true ;
                                
                                        Value = default(T) ;
                                

                                public static bool
                                TryGetValue<T>
                                (
                                this object Source
                                ,
                                out T Value
                                )
                                {
                                bool result = false ;

                                Value = default(T) ;

                                L Offline
                                L Offline
                                Luc Pattyn
                                wrote on last edited by
                                #17

                                I agree. :)

                                Luc Pattyn [My Articles] Nil Volentibus Arduum

                                1 Reply Last reply
                                0
                                • P PIEBALDconsult

                                  Well it's zero, right?

                                  RaviBeeR Offline
                                  RaviBeeR Offline
                                  RaviBee
                                  wrote on last edited by
                                  #18

                                  Yessir, it is. /ravi

                                  My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                  1 Reply Last reply
                                  0
                                  • L Lost User

                                    Do we actually care, if the value isn't being used?

                                    string badNumericString = "Bogus";
                                    Decimal foo; // will be initialized to 0 by the runtime
                                    if (!Decimal.TryParse (badNumericString, out foo)) foo = 1; // default value here

                                    ..and if the TryParse don't use the value, it'll probably initialize it with the same value it initializes an empty variable. Since the variable hasn't been set (according to application logic), we can't be sure about the value unless we explicitly set it. (Future versions of .NET might display other behavior)

                                    Bastard Programmer from Hell :suss:

                                    RaviBeeR Offline
                                    RaviBeeR Offline
                                    RaviBee
                                    wrote on last edited by
                                    #19

                                    Eddy Vluggen wrote:

                                    Do we actually care, if the value isn't being used?

                                    It is being used.  The example I gave was intentionally limited to focus on the question.  In my app, foo (not its real name) is used after the TryParse() executes.  Different things happen depending on whether foo is Decimal.MinValue. /ravi

                                    My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                    1 Reply Last reply
                                    0
                                    • L Luc Pattyn

                                      That is what the doc[^] says. This entire thread seams to suggest no-one reads or beliefs it. :)

                                      Luc Pattyn [My Articles] Nil Volentibus Arduum

                                      RaviBeeR Offline
                                      RaviBeeR Offline
                                      RaviBee
                                      wrote on last edited by
                                      #20

                                      You are right in assuming I didn't read the doc. :) /ravi

                                      My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                      1 Reply Last reply
                                      0
                                      • RaviBeeR RaviBee

                                        What would you expect foo to be after this code fragment runs?  Post your answer without first peeking at the docs! :-D

                                        string badNumericString = "Bogus";
                                        Decimal foo = Decimal.MinValue;
                                        bool status = Decimal.TryParse (badNumericString, out foo); // status is false, as expected

                                        Answer:

                                        • Decimal.MinValue (since the parse failed)
                                        • Something else (if so, what?)

                                        /ravi

                                        My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                        D Offline
                                        D Offline
                                        dybs
                                        wrote on last edited by
                                        #21

                                        I think foo would be zero, but that's just a guess. I think Int32.TryParse and Double.TryParse set the out parameter to zero if the parse fails, but I don't recall. If TryParse fails, I usually set the value to some known default that I can handle - I don't care what TryParse sets it to, especially is MS decides to change it down the road.

                                        The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

                                        RaviBeeR 1 Reply Last reply
                                        0
                                        • D dybs

                                          I think foo would be zero, but that's just a guess. I think Int32.TryParse and Double.TryParse set the out parameter to zero if the parse fails, but I don't recall. If TryParse fails, I usually set the value to some known default that I can handle - I don't care what TryParse sets it to, especially is MS decides to change it down the road.

                                          The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

                                          RaviBeeR Offline
                                          RaviBeeR Offline
                                          RaviBee
                                          wrote on last edited by
                                          #22

                                          You're absolutely correct.

                                          dybs wrote:

                                          If TryParse fails, I usually set the value to some known default that I can handle

                                          I agree that's the advisable thing to do. /ravi

                                          My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups