What does it mean?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jason Huang

    What does it mean?

    Hi,

    Would someone explain the following coding more detail for me? What's the
    ( ) for?
    CurrentText = (TextBox)e.Item .Cells[i].Controls[0];
    Thanks.

    Jason


  • Publicjoe

    #2
    Re: What does it mean?

    This is a cast.(type casting), have a look at this article to see if it
    explains things for you


    Hope this helps

    Publicjoe

    C# Tutorial at http://www.publicjoe.f9.co.uk/csharp/tut.html
    C# Ebook at http://www.publicjoe.f9.co.uk/csharp/samples/ebook.html
    VB Tutorial at http://www.publicjoe.f9.co.uk/vbnet/vbnet.html
    VB Ebook at http://www.publicjoe.f9.co.uk/vbnet/samples/ebook.html
    Mirrors at http://dowhileloop.com/publicjoe/ and


    "Jason Huang" <JasonHuang8888 @hotmail.com> wrote in message
    news:OlmklZzaFH A.724@TK2MSFTNG P12.phx.gbl...[color=blue]
    > Hi,
    >
    > Would someone explain the following coding more detail for me? What's the
    > ( ) for?
    > CurrentText = (TextBox)e.Item .Cells[i].Controls[0];
    > Thanks.
    >
    > Jason
    >
    >[/color]


    Comment

    • Søren Reinke

      #3
      Re: What does it mean?


      "Jason Huang" <JasonHuang8888 @hotmail.com> wrote in message
      news:OlmklZzaFH A.724@TK2MSFTNG P12.phx.gbl...[color=blue]
      > Hi,
      >
      > Would someone explain the following coding more detail for me? What's the
      > ( ) for?
      > CurrentText = (TextBox)e.Item .Cells[i].Controls[0];[/color]

      Typecasting, so that the result of 'e.Item.Cells[i].Controls[0];' is an
      object of the type 'TextBox'

      --
      Søren Reinke
      www.Xray-Mag.com/ - Your free diving magazin on the net.
      Current issue Diving in North America, 99 pages.
      Download it in PDF


      Comment

      • Nick Malik [Microsoft]

        #4
        Re: What does it mean?

        Looks like 'e' is a grid or list of some kind... possibly a third party
        control.
        The Item method allows you to dig into the list elements of the control.

        Cells[i] is an array of cells or list elements. This looks like a single
        list or a one-column grid?
        So, the value [i] selects the "i"th element in the list (usually counting
        from zero).
        Note: if the list does not have "i" elements in it, then this statement will
        generate an error.

        It looks like each cell in your control can hold multiple controls
        (perfectly valid). However, the original programmer expects that there is
        at least one control in that cell. s/he refers to that first control in the
        cell as controls[0]. Note: if the cell does not contain a control, this
        statement will generate an error.

        The same developer expects that the first control is a text box. Note: if
        it is not a textbox, this statement will generate an error.

        The developer used casting to let the language know that it should treat the
        first control, in the controls list, as a text box.
        That value is assigned to the variable CurrentText

        Note: if the variable CurrentText is a string variable, then the original
        developer should probably have called a method on the TextBox to return the
        actual text contents. That is probably the intent, although it isn't coded
        that way.

        Therefore, assuming this statement compiles, this statement will return the
        textbox control from a cell in an editable list or grid, or it throws one of
        many runtime errors.

        --
        --- Nick Malik [Microsoft]
        MCSD, CFPS, Certified Scrummaster


        Disclaimer: Opinions expressed in this forum are my own, and not
        representative of my employer.
        I do not answer questions on behalf of my employer. I'm just a
        programmer helping programmers.
        --
        "Jason Huang" <JasonHuang8888 @hotmail.com> wrote in message
        news:OlmklZzaFH A.724@TK2MSFTNG P12.phx.gbl...[color=blue]
        > Hi,
        >
        > Would someone explain the following coding more detail for me? What's the
        > ( ) for?
        > CurrentText = (TextBox)e.Item .Cells[i].Controls[0];
        > Thanks.
        >
        > Jason
        >
        >[/color]


        Comment

        • Frisky

          #5
          Re: What does it mean?

          The previous posts are correct and sufficient.

          Might I recommend that you use "as" instead of a cast. This is for
          converting compatible types. It will only perform reference conversions and
          boxing conversions. The "as" is equivalent to:

          expression is type ? (type) expression : (type) null

          Note the extra safety in checking the type prior to performing the
          conversion. Should the expression in the above not be of the type you are
          looking for, it returns null. If you cast like this:

          (type) expression

          and the type in the expression is not compatible with type, then a
          System.InvalidC astException exception will be thrown.

          Hope this helps...

          Frisky


          "Jason Huang" <JasonHuang8888 @hotmail.com> wrote in message
          news:OlmklZzaFH A.724@TK2MSFTNG P12.phx.gbl...[color=blue]
          > Hi,
          >
          > Would someone explain the following coding more detail for me? What's the
          > ( ) for?
          > CurrentText = (TextBox)e.Item .Cells[i].Controls[0];
          > Thanks.
          >
          > Jason
          >
          >[/color]


          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: What does it mean?

            Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=blue]
            > The previous posts are correct and sufficient.
            >
            > Might I recommend that you use "as" instead of a cast. This is for
            > converting compatible types. It will only perform reference conversions and
            > boxing conversions. The "as" is equivalent to:
            >
            > expression is type ? (type) expression : (type) null
            >
            > Note the extra safety in checking the type prior to performing the
            > conversion. Should the expression in the above not be of the type you are
            > looking for, it returns null. If you cast like this:
            >
            > (type) expression
            >
            > and the type in the expression is not compatible with type, then a
            > System.InvalidC astException exception will be thrown.[/color]

            "as" and casting serve slightly different purposes. When it is a
            programming error for the value of a variable *not* to be a reference
            to a certain type of object, I use a cast. If it's not an error, and I
            just want to do something different if it's not an appropriate
            reference, that's when as is useful.

            For instance, taking values out of a private ArrayList, I'd always use
            a cast - if the value isn't of the right type, I've got an error
            elsewhere in my code, and an InvalidCastExce ption is just as good as
            anything else. Otherwise you get a lot of code bloat for checking for
            null unnecessarily.

            --
            Jon Skeet - <skeet@pobox.co m>
            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

            If replying to the group, please do not mail me too

            Comment

            • Frisky

              #7
              Re: What does it mean?

              Jon,

              I complely agree with you. There certainly are reasons to cast versus using
              "as". However, I believe the reasons are for casting values, which "as" does
              not handle.

              Otherwise, use "as". It is safer and more efficient at runtime. "As" and
              "is" do not perform user-defined conversions. They succeed only if the
              runtime type matches the sought type. The never construct a new object to
              satisfy a request.

              So, if I were to code something like this, I might write:

              BusinessType myBusiness = Factory.CreateO bject() as BusinessType;
              if (myBusiness != null) {
              myBusiness.DoSt uff();
              }

              If I were to use the cast, it would look like:

              try {
              BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
              if (yourBusiness != null) {
              yourBusiness.Do Stuff();
              }
              }
              catch (Exception ex) {
              System.Diagnost ic.Debug.WriteL ine("Exception: " + ex.ToString());
              // handle exception
              }

              So, it is a lot less code when you have to check.

              As far as a private array goes, I agree that you could simply cast the
              value. But, there is no reason to do this. The "as" is more efficient
              because it only checks the runtime types. If they don't match the criteria,
              null is returned. And, if you use typed collections like we do, there is no
              reason to cast anyway.

              But back to the problem described here. This is not a private array. In
              point of fact, this is a very public and very variant array. The check is
              warrented. We do not know what type of control might be in the Control array
              of a particular Cell of a particular Item. This is a classic example of why
              to check.

              I am not sure what you mean by bloat? (So many people are using that these
              days.) Is it the few extra bytes of code I generated? I have already shown
              that the "as" is more efficient and requires less code to implement. I know,
              I know, your gonna say you could have just said:

              BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();

              or more along the lines of the example you gave:

              YourObject yourObject = (YourObject) yourArray[index];

              But, the "as" equivalent:

              YourObject yourObject = yourArray[index] as YourObject;

              is no less efficient than the other version, does not throw (which is really
              expensive), and will not attempt to perform user conversions or create a new
              object.


              BTW: Am I stepping on your turf or someting?

              --
              Frisky

              Intellectuals solve problems; geniuses prevent them. ~ Albert Einstein
              "Jon Skeet [C# MVP]" <skeet@pobox.co m> wrote in message
              news:MPG.1d11e5 b6d662b11a98c2a 2@msnews.micros oft.com...[color=blue]
              > Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=green]
              >> The previous posts are correct and sufficient.
              >>
              >> Might I recommend that you use "as" instead of a cast. This is for
              >> converting compatible types. It will only perform reference conversions
              >> and
              >> boxing conversions. The "as" is equivalent to:
              >>
              >> expression is type ? (type) expression : (type) null
              >>
              >> Note the extra safety in checking the type prior to performing the
              >> conversion. Should the expression in the above not be of the type you are
              >> looking for, it returns null. If you cast like this:
              >>
              >> (type) expression
              >>
              >> and the type in the expression is not compatible with type, then a
              >> System.InvalidC astException exception will be thrown.[/color]
              >
              > "as" and casting serve slightly different purposes. When it is a
              > programming error for the value of a variable *not* to be a reference
              > to a certain type of object, I use a cast. If it's not an error, and I
              > just want to do something different if it's not an appropriate
              > reference, that's when as is useful.
              >
              > For instance, taking values out of a private ArrayList, I'd always use
              > a cast - if the value isn't of the right type, I've got an error
              > elsewhere in my code, and an InvalidCastExce ption is just as good as
              > anything else. Otherwise you get a lot of code bloat for checking for
              > null unnecessarily.
              >
              > --
              > Jon Skeet - <skeet@pobox.co m>
              > http://www.pobox.com/~skeet
              > If replying to the group, please do not mail me too[/color]


              Comment

              • Frisky

                #8
                Re: What does it mean?

                Jon,

                I complely agree with you. There certainly are reasons to cast versus using
                "as". However, I believe the reasons are for casting values, which "as" does
                not handle.

                Otherwise, use "as". It is safer and more efficient at runtime. "As" and
                "is" do not perform user-defined conversions. They succeed only if the
                runtime type matches the sought type. The never construct a new object to
                satisfy a request.

                So, if I were to code something like this, I might write:

                BusinessType myBusiness = Factory.CreateO bject() as BusinessType;
                if (myBusiness != null) {
                myBusiness.DoSt uff();
                }

                If I were to use the cast, it would look like:

                try {
                BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                if (yourBusiness != null) {
                yourBusiness.Do Stuff();
                }
                }
                catch (Exception ex) {
                System.Diagnost ic.Debug.WriteL ine("Exception: " + ex.ToString());
                // handle exception
                }

                So, it is a lot less code when you have to check.

                As far as a private array goes, I agree that you could simply cast the
                value. But, there is no reason to do this. The "as" is more efficient
                because it only checks the runtime types. If they don't match the criteria,
                null is returned. And, if you use typed collections like we do, there is no
                reason to cast anyway.

                But back to the problem described here. This is not a private array. In
                point of fact, this is a very public and very variant array. The check is
                warrented. We do not know what type of control might be in the Control array
                of a particular Cell of a particular Item. This is a classic example of why
                to check.

                I am not sure what you mean by bloat? (So many people are using that these
                days.) Is it the few extra bytes of code I generated? I have already shown
                that the "as" is more efficient and requires less code to implement. I know,
                I know, your gonna say you could have just said:

                BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();

                or more along the lines of the example you gave:

                YourObject yourObject = (YourObject) yourArray[index];

                But, the "as" equivalent:

                YourObject yourObject = yourArray[index] as YourObject;

                is no less efficient than the other version, does not throw (which is really
                expensive), and will not attempt to perform user conversions or create a new
                object.


                BTW: Am I stepping on your turf or someting?

                --
                Frisky

                Intellectuals solve problems; geniuses prevent them. ~ Albert Einstein
                "Jon Skeet [C# MVP]" <skeet@pobox.co m> wrote in message
                news:MPG.1d11e5 b6d662b11a98c2a 2@msnews.micros oft.com...[color=blue]
                > Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=green]
                >> The previous posts are correct and sufficient.
                >>
                >> Might I recommend that you use "as" instead of a cast. This is for
                >> converting compatible types. It will only perform reference conversions
                >> and
                >> boxing conversions. The "as" is equivalent to:
                >>
                >> expression is type ? (type) expression : (type) null
                >>
                >> Note the extra safety in checking the type prior to performing the
                >> conversion. Should the expression in the above not be of the type you are
                >> looking for, it returns null. If you cast like this:
                >>
                >> (type) expression
                >>
                >> and the type in the expression is not compatible with type, then a
                >> System.InvalidC astException exception will be thrown.[/color]
                >
                > "as" and casting serve slightly different purposes. When it is a
                > programming error for the value of a variable *not* to be a reference
                > to a certain type of object, I use a cast. If it's not an error, and I
                > just want to do something different if it's not an appropriate
                > reference, that's when as is useful.
                >
                > For instance, taking values out of a private ArrayList, I'd always use
                > a cast - if the value isn't of the right type, I've got an error
                > elsewhere in my code, and an InvalidCastExce ption is just as good as
                > anything else. Otherwise you get a lot of code bloat for checking for
                > null unnecessarily.
                >
                > --
                > Jon Skeet - <skeet@pobox.co m>
                > http://www.pobox.com/~skeet
                > If replying to the group, please do not mail me too[/color]


                Comment

                • Jon Skeet [C# MVP]

                  #9
                  Re: What does it mean?

                  Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=blue]
                  > I complely agree with you. There certainly are reasons to cast versus using
                  > "as". However, I believe the reasons are for casting values, which "as" does
                  > not handle.
                  >
                  > Otherwise, use "as". It is safer and more efficient at runtime. "As" and
                  > "is" do not perform user-defined conversions. They succeed only if the
                  > runtime type matches the sought type. The never construct a new object to
                  > satisfy a request.
                  >
                  > So, if I were to code something like this, I might write:
                  >
                  > BusinessType myBusiness = Factory.CreateO bject() as BusinessType;
                  > if (myBusiness != null) {
                  > myBusiness.DoSt uff();
                  > }
                  >
                  > If I were to use the cast, it would look like:
                  >
                  > try {
                  > BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                  > if (yourBusiness != null) {
                  > yourBusiness.Do Stuff();
                  > }
                  > }
                  > catch (Exception ex) {
                  > System.Diagnost ic.Debug.WriteL ine("Exception: " + ex.ToString());
                  > // handle exception
                  > }
                  >
                  > So, it is a lot less code when you have to check.[/color]

                  You should almost never *actually* catch exceptions at the point
                  they're generated. They should bubble up.

                  Any proper factory that's asked to create an object should either throw
                  an exception or create the appropriate object. If it's returning
                  something other than the appropriate type I'm expecting, I almost
                  certainly want an exception. I'd write your code as:

                  BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();

                  I don't see the problem.
                  [color=blue]
                  > As far as a private array goes, I agree that you could simply cast the
                  > value. But, there is no reason to do this. The "as" is more efficient
                  > because it only checks the runtime types. If they don't match the criteria,
                  > null is returned. And, if you use typed collections like we do, there is no
                  > reason to cast anyway.[/color]

                  Casting and "as" are equally efficient when there aren't conversions
                  involved, and that's decided at compile-time, not runtime.
                  [color=blue]
                  > But back to the problem described here. This is not a private array. In
                  > point of fact, this is a very public and very variant array. The check is
                  > warrented. We do not know what type of control might be in the Control array
                  > of a particular Cell of a particular Item. This is a classic example of why
                  > to check.[/color]

                  If you genuinely don't know *and* you want to handle the situation
                  where the result isn't a TextBox, sure. I would probably just throw an
                  exception there anyway though, in most cases.
                  [color=blue]
                  > I am not sure what you mean by bloat? (So many people are using that these
                  > days.) Is it the few extra bytes of code I generated? I have already shown
                  > that the "as" is more efficient and requires less code to implement.[/color]

                  No, because you're checking for null manually rather than letting the
                  cast do the check for you and throw the exception appropriately. The
                  important part of the bloat here is the source bloat - the extra check
                  takes up precious space that could be getting on with what you actually
                  want to be doing. That's the joy of using exceptions rather than return
                  values - most of your actual code gets on with what you want to do,
                  rather than error checking.
                  [color=blue]
                  > I know,
                  > I know, your gonna say you could have just said:
                  >
                  > BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                  >
                  > or more along the lines of the example you gave:
                  >
                  > YourObject yourObject = (YourObject) yourArray[index];[/color]

                  ArrayList, actually. If you've got an actual array, I'd expect it to be
                  the right type to start with.
                  [color=blue]
                  > But, the "as" equivalent:
                  >
                  > YourObject yourObject = yourArray[index] as YourObject;
                  >
                  > is no less efficient than the other version, does not throw (which is really
                  > expensive), and will not attempt to perform user conversions or create a new
                  > object.[/color]

                  But I almost always *want* it to throw - and to get the "as" version to
                  throw, you have to put more code in.

                  As for user conversions - as I said before, that's decided at compile-
                  time, not run-time, so there's no bloat there, and the only times they
                  *would* be used would be when I'd want them anyway. No new objects will
                  be created when conversions aren't invoked.
                  [color=blue]
                  > BTW: Am I stepping on your turf or someting?[/color]

                  Not at all. I just happen to disagree with you on code style.

                  --
                  Jon Skeet - <skeet@pobox.co m>
                  Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                  If replying to the group, please do not mail me too

                  Comment

                  • Frisky

                    #10
                    Re: What does it mean?

                    Intellectuals solve problems; geniuses prevent them. ~ Albert Einstein
                    "Jon Skeet [C# MVP]" <skeet@pobox.co m> wrote in message
                    news:MPG.1d1342 3c649a464c98c2b c@msnews.micros oft.com...[color=blue]
                    > Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=green]
                    >> I complely agree with you. There certainly are reasons to cast versus
                    >> using
                    >> "as". However, I believe the reasons are for casting values, which "as"
                    >> does
                    >> not handle.
                    >>
                    >> Otherwise, use "as". It is safer and more efficient at runtime. "As" and
                    >> "is" do not perform user-defined conversions. They succeed only if the
                    >> runtime type matches the sought type. The never construct a new object to
                    >> satisfy a request.
                    >>
                    >> So, if I were to code something like this, I might write:
                    >>
                    >> BusinessType myBusiness = Factory.CreateO bject() as BusinessType;
                    >> if (myBusiness != null) {
                    >> myBusiness.DoSt uff();
                    >> }
                    >>
                    >> If I were to use the cast, it would look like:
                    >>
                    >> try {
                    >> BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                    >> if (yourBusiness != null) {
                    >> yourBusiness.Do Stuff();
                    >> }
                    >> }
                    >> catch (Exception ex) {
                    >> System.Diagnost ic.Debug.WriteL ine("Exception: " + ex.ToString());
                    >> // handle exception
                    >> }
                    >>
                    >> So, it is a lot less code when you have to check.[/color]
                    >
                    > You should almost never *actually* catch exceptions at the point
                    > they're generated. They should bubble up.
                    >
                    > Any proper factory that's asked to create an object should either throw
                    > an exception or create the appropriate object. If it's returning
                    > something other than the appropriate type I'm expecting, I almost
                    > certainly want an exception. I'd write your code as:
                    >
                    > BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                    >
                    > I don't see the problem.[/color]

                    <grin>Like I said you would say. (See below)</grin>

                    Stick to the point. You should use "as" not casts whereever possible. Where
                    your catch does not change which you should use.

                    But, if you would like to save yourself all of the exception processing, a
                    simple check for null will do the trick. You code will be faster, and you
                    won't have to find another place to hide some exception code. You have
                    prevented the problem prior to it occurring.

                    In most instances, the exception, which must eventually be caught, will end
                    up doing nothing. By bubbling the throw up, I just skipped the rest of the
                    code in that method. So, if the rest of the code would have run, it won't
                    now. This may be what you wanted, but with the null check you can do either.
                    And the null check costs virtually nothing.
                    [color=blue][color=green]
                    >> As far as a private array goes, I agree that you could simply cast the
                    >> value. But, there is no reason to do this. The "as" is more efficient
                    >> because it only checks the runtime types. If they don't match the
                    >> criteria,
                    >> null is returned. And, if you use typed collections like we do, there is
                    >> no
                    >> reason to cast anyway.[/color]
                    >
                    > Casting and "as" are equally efficient when there aren't conversions
                    > involved, and that's decided at compile-time, not runtime.[/color]

                    Are you conceeding my point? So, "as" and cast are equivalent in the worst
                    case, and "as" is faster in the best case. Like I said, always use "as"
                    unless you can't.

                    The code example given is most definitley a runtime type check. There is
                    know way the compiler can possibly know if the type of an item placed in the
                    control array is a particular control. It only knows that it "is a" Control.
                    This check and possible exception are generated at runtime.

                    (Check out the article http://www.codeproject.com/csharp/csharpcasts.asp)
                    While I have not verified his results, my results were similar.
                    [color=blue][color=green]
                    >> But back to the problem described here. This is not a private array. In
                    >> point of fact, this is a very public and very variant array. The check is
                    >> warrented. We do not know what type of control might be in the Control
                    >> array
                    >> of a particular Cell of a particular Item. This is a classic example of
                    >> why
                    >> to check.[/color]
                    >
                    > If you genuinely don't know *and* you want to handle the situation
                    > where the result isn't a TextBox, sure. I would probably just throw an
                    > exception there anyway though, in most cases.[/color]

                    There is nothing here that says you should not use "as". Again, as you
                    stated above, it is at least as efficient in the worst case. Oh, and if you
                    don't check for null, it will still throw. But see below for why you might
                    not want to do that.
                    [color=blue][color=green]
                    >> I am not sure what you mean by bloat? (So many people are using that
                    >> these
                    >> days.) Is it the few extra bytes of code I generated? I have already
                    >> shown
                    >> that the "as" is more efficient and requires less code to implement.[/color]
                    >
                    > No, because you're checking for null manually rather than letting the
                    > cast do the check for you and throw the exception appropriately. The
                    > important part of the bloat here is the source bloat - the extra check
                    > takes up precious space that could be getting on with what you actually
                    > want to be doing. That's the joy of using exceptions rather than return
                    > values - most of your actual code gets on with what you want to do,
                    > rather than error checking.[/color]

                    Well, this of course depends on how you write your code. If you don't mind
                    poor performance, throw all over the place. The combined "as" and null check
                    are still way less impact to your code that the cast. And, when you do
                    throw, the cost is huge.
                    [color=blue][color=green]
                    >> I know,
                    >> I know, your gonna say you could have just said:
                    >>
                    >> BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                    >>
                    >> or more along the lines of the example you gave:
                    >>
                    >> YourObject yourObject = (YourObject) yourArray[index];[/color]
                    >
                    > ArrayList, actually. If you've got an actual array, I'd expect it to be
                    > the right type to start with.[/color]

                    First, I do not know how you would know, based on the code here, exactly how
                    this array was implemented. And if it was trully an array, what type it was
                    defined on. An array does not have to be of your particular type. It might
                    be of a base type or object type.

                    And yes, it works with ArrayList, HashTables, etc. too.
                    [color=blue][color=green]
                    >> But, the "as" equivalent:
                    >>
                    >> YourObject yourObject = yourArray[index] as YourObject;
                    >>
                    >> is no less efficient than the other version, does not throw (which is
                    >> really
                    >> expensive), and will not attempt to perform user conversions or create a
                    >> new
                    >> object.[/color]
                    >
                    > But I almost always *want* it to throw - and to get the "as" version to
                    > throw, you have to put more code in.
                    >
                    > As for user conversions - as I said before, that's decided at compile-
                    > time, not run-time, so there's no bloat there, and the only times they
                    > *would* be used would be when I'd want them anyway. No new objects will
                    > be created when conversions aren't invoked.[/color]

                    First, here is fundamental difference. I *don't want* to throw. If I am
                    going to throw, I know there is a *huge* overhead. I need to be judicious
                    and make sure that throwing is correct for this particular problem.
                    Validating UI objects should almost always involve checking and not throwing
                    because of performance. Also, again, I can continue with other updates to
                    the UI even if this one control is not behaving.

                    Second, there is no more code required to throw. When the "as" is performed,
                    if it fails, you get null. If you attempt to use the null, as in the long
                    string of code originally shown, you will most certainly throw an exception.

                    I don't know how you would know based on the code shown if a user conversion
                    exists or not. Are you saying because we havn't shown one. I have seen this
                    assumption bite many people. But, again, check out the article, and perform
                    your own tests. I am not worried about bloat, but performance.

                    I don't think either of these methods bloats the code. One is just faster
                    than the other. (Not bloat; performance) And the slower casting method does
                    not afford me any value add.
                    [color=blue][color=green]
                    >> BTW: Am I stepping on your turf or someting?[/color]
                    >
                    > Not at all. I just happen to disagree with you on code style.[/color]

                    Just though I would ask. And, actually, the reason I asked is because of the
                    reason you stated. You have disagreed with everything I wrote. But, I have
                    noticed similar commnents in other articles in this group, which you
                    ignored. ???

                    I certainly do not mind that you and I going back and forth. This is
                    healthy, and both of us stand to learn something. Right?

                    However, I would perfer a more contructive approach. A cooperative attitude
                    would be nice. Even if you don't like my code style. I like it a lot. And I
                    respect yours.
                    [color=blue]
                    > --
                    > Jon Skeet - <skeet@pobox.co m>
                    > http://www.pobox.com/~skeet
                    > If replying to the group, please do not mail me too[/color]


                    Comment

                    • Jon Skeet [C# MVP]

                      #11
                      Re: What does it mean?

                      Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=blue][color=green]
                      > > BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                      > >
                      > > I don't see the problem.[/color]
                      >
                      > <grin>Like I said you would say. (See below)</grin>
                      >
                      > Stick to the point. You should use "as" not casts whereever possible. Where
                      > your catch does not change which you should use.[/color]

                      Yes it does. It makes a huge difference to the code. When you use as
                      and test for nullity, you have to have that check *everywhere*. You
                      gave sample code which mimicked that, but catching the exception - and
                      unsurprisingly, it came out looking nasty. Change that to catching
                      exceptions centrally, and you end up with *much* cleaner code.
                      [color=blue]
                      > But, if you would like to save yourself all of the exception processing, a
                      > simple check for null will do the trick. You code will be faster, and you
                      > won't have to find another place to hide some exception code. You have
                      > prevented the problem prior to it occurring.[/color]

                      No, you haven't prevented the problem - you've just decided to
                      understand the problem manually rather than automatically. I don't
                      believe the code will be faster, either - why would it be? Both are
                      doing the same thing, asking the runtime to do an "as" and then
                      checking for nullity. (That's what a cast does internally.)
                      [color=blue]
                      > In most instances, the exception, which must eventually be caught, will end
                      > up doing nothing. By bubbling the throw up, I just skipped the rest of the
                      > code in that method. So, if the rest of the code would have run, it won't
                      > now. This may be what you wanted, but with the null check you can do either.
                      > And the null check costs virtually nothing.[/color]

                      *If* you want the code to do nothing, yes, you should use "as". I find
                      that case is much, much rarer than the case where you know that if
                      there's an unexpected type there, it's due to a programming error, and
                      you want to stop what you're doing as soon as possible.
                      [color=blue][color=green]
                      > > Casting and "as" are equally efficient when there aren't conversions
                      > > involved, and that's decided at compile-time, not runtime.[/color]
                      >
                      > Are you conceeding my point?[/color]

                      Not at all.
                      [color=blue]
                      > So, "as" and cast are equivalent in the worst case, and "as" is
                      > faster in the best case.[/color]

                      In your best case, the operations are entirely distinct - they do
                      different things. In your worst case, they're equivalent, and yet you
                      claim above that it's faster.
                      [color=blue]
                      > Like I said, always use "as" unless you can't.[/color]

                      If you like doing all your error handling manually - I don't.
                      [color=blue]
                      > The code example given is most definitley a runtime type check. There is
                      > know way the compiler can possibly know if the type of an item placed in the
                      > control array is a particular control. It only knows that it "is a" Control.
                      > This check and possible exception are generated at runtime.[/color]

                      I don't think you read my post carefully enough. The compiler decides
                      at compile-time whether or not it's just a cast, or whether it's a
                      user-defined conversion.
                      [color=blue]
                      > (Check out the article http://www.codeproject.com/csharp/csharpcasts.asp)
                      > While I have not verified his results, my results were similar.[/color]

                      I'll try it some time. Not that I believe the performance difference is
                      ever going to be significant in many real applications - whereas the
                      cost of failing to check for nullity *could* be significant, and all
                      too easy to miss.
                      [color=blue][color=green]
                      > > If you genuinely don't know *and* you want to handle the situation
                      > > where the result isn't a TextBox, sure. I would probably just throw an
                      > > exception there anyway though, in most cases.[/color]
                      >
                      > There is nothing here that says you should not use "as".[/color]

                      No, but there's nothing to say you shouldn't use a cast either - and
                      the difference is between:

                      TextBox tb = (TextBox) control;

                      and:

                      TextBox tb = control as TextBox;
                      if (tb==null)
                      {
                      throw new SomeOtherExcept ion();
                      }

                      Do you really find the second code clearer?
                      [color=blue]
                      > Again, as you
                      > stated above, it is at least as efficient in the worst case. Oh, and if you
                      > don't check for null, it will still throw. But see below for why you might
                      > not want to do that.[/color]

                      It will only throw in situations where you immediately use it though -
                      which isn't always the case. What if you then pass it into a method
                      which happily accepts nulls, but treats them differently? Very subtle
                      bugs can be introduced that way...
                      [color=blue][color=green]
                      > > No, because you're checking for null manually rather than letting the
                      > > cast do the check for you and throw the exception appropriately. The
                      > > important part of the bloat here is the source bloat - the extra check
                      > > takes up precious space that could be getting on with what you actually
                      > > want to be doing. That's the joy of using exceptions rather than return
                      > > values - most of your actual code gets on with what you want to do,
                      > > rather than error checking.[/color]
                      >
                      > Well, this of course depends on how you write your code. If you don't mind
                      > poor performance, throw all over the place. The combined "as" and null check
                      > are still way less impact to your code that the cast. And, when you do
                      > throw, the cost is huge.[/color]

                      It's not huge. It's about 100,000th of a second on my (not top of the
                      range) laptop. That's not huge unless you're doing it time and time
                      again, which indicates other problems in your code.

                      I *do* throw all over the place - pretty much whenever I detect an
                      error condition. Does the performance get hit? No, because there rarely
                      *is* an error condition, and if there is, there's the hit of *one*
                      exception, rather than hundreds of thousands. Like I've said,
                      exceptions costing real life performance is more of a myth than reality
                      in almost all applications.
                      [color=blue][color=green]
                      > > ArrayList, actually. If you've got an actual array, I'd expect it to be
                      > > the right type to start with.[/color]
                      >
                      > First, I do not know how you would know, based on the code here, exactly how
                      > this array was implemented. And if it was trully an array, what type it was
                      > defined on. An array does not have to be of your particular type. It might
                      > be of a base type or object type.[/color]

                      Usually when I'm dealing with arrays, they're member variables of my
                      own class, and they're usually of the right type. I rarely have to cast
                      from arrays.

                      <snip>
                      [color=blue][color=green]
                      > > As for user conversions - as I said before, that's decided at compile-
                      > > time, not run-time, so there's no bloat there, and the only times they
                      > > *would* be used would be when I'd want them anyway. No new objects will
                      > > be created when conversions aren't invoked.[/color]
                      >
                      > First, here is fundamental difference. I *don't want* to throw. If I am
                      > going to throw, I know there is a *huge* overhead.[/color]

                      Well, there's a ~0.001ms overhead. I don't think that's huge, unless
                      you're planning to do it thousands of times - which basically isn't
                      going to happen here.
                      [color=blue]
                      > I need to be judicious
                      > and make sure that throwing is correct for this particular problem.
                      > Validating UI objects should almost always involve checking and not throwing
                      > because of performance. Also, again, I can continue with other updates to
                      > the UI even if this one control is not behaving.[/color]

                      Validating UI *input* should almost always involve checking (although
                      not so much for performance reasons - a human in front of a UI
                      certainly can't hit keys or move the mouse quickly enough to make it a
                      problem to throw an exception every time they do so). Validating
                      whether a control is actually what it should be? That doesn't need
                      checking manually. If it's wrong, the code itself is screwed up.
                      [color=blue]
                      > Second, there is no more code required to throw. When the "as" is performed,
                      > if it fails, you get null. If you attempt to use the null, as in the long
                      > string of code originally shown, you will most certainly throw an exception.[/color]

                      In this particular case - what about when you're passing it elsewhere,
                      or not using it immediately?
                      [color=blue]
                      > I don't know how you would know based on the code shown if a user conversion
                      > exists or not.[/color]

                      Because there's no defined conversion between Control and TextBox.
                      Operators are overloaded, not overridden - it's a compile-time thing,
                      not a run-time thing. If the actual control were some third-party
                      control which didn't inherit from TextBox, but had a user-defined
                      conversion to it, that wouldn't be performed in the casting case,
                      because the compiler doesn't know about it at compile-time.
                      [color=blue]
                      > Are you saying because we havn't shown one. I have seen this
                      > assumption bite many people. But, again, check out the article, and perform
                      > your own tests. I am not worried about bloat, but performance.[/color]

                      I believe you are artificially worried about performance, perhaps
                      partly based on previous bad experiences of very odd situations such as
                      the one you mentioned where you didn't know what resources were in an
                      assembly. (Any reason not to find them out using
                      GetManifestReso urceNames? Better than asking speculatively in that
                      situation, I'd say.)
                      [color=blue]
                      > I don't think either of these methods bloats the code. One is just faster
                      > than the other. (Not bloat; performance) And the slower casting method does
                      > not afford me any value add.[/color]

                      Whereas it gives me the following benefits:
                      1) Shorter code where the main success path is clearer, not hidden by
                      potential errors which can be handled (by throwing) by the runtime

                      2) Less room for accidentally forgetting the nullity check.
                      [color=blue][color=green][color=darkred]
                      > >> BTW: Am I stepping on your turf or someting?[/color]
                      > >
                      > > Not at all. I just happen to disagree with you on code style.[/color]
                      >
                      > Just though I would ask. And, actually, the reason I asked is because of the
                      > reason you stated. You have disagreed with everything I wrote. But, I have
                      > noticed similar commnents in other articles in this group, which you
                      > ignored. ???[/color]

                      I don't respond to every article which I might disagree with - there
                      wouldn't be time. You'll find I *do* tend to respond to people who
                      claim there's a "huge overhead" in throwing exceptions though - they
                      tend not to understand that exceptions can be thrown tens to hundreds
                      of thousands of times per second in release mode (which is where
                      performance matters). Once again, the actual cost of throwing an
                      exception is almost *never* a bottleneck in real applications. Failure
                      to check a return value is very easy to do though - and I'd always
                      rather have a slight performance hit than a bug.
                      [color=blue]
                      > I certainly do not mind that you and I going back and forth. This is
                      > healthy, and both of us stand to learn something. Right?[/color]

                      Absolutely.
                      [color=blue]
                      > However, I would perfer a more contructive approach. A cooperative attitude
                      > would be nice. Even if you don't like my code style. I like it a lot. And I
                      > respect yours.[/color]

                      I don't think I've been any less respectful to you than you have to me.

                      --
                      Jon Skeet - <skeet@pobox.co m>
                      Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                      If replying to the group, please do not mail me too

                      Comment

                      • Jon Skeet [C# MVP]

                        #12
                        Re: What does it mean?

                        Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:

                        <snip>
                        [color=blue]
                        > (Check out the article http://www.codeproject.com/csharp/csharpcasts.asp)
                        > While I have not verified his results, my results were similar.[/color]

                        The graph on that page bothered me, so I tried my own test. I normally
                        got results which were within about 5% of each other - sometimes one
                        approach being faster, sometimes the other. Nothing significant, in
                        other words.

                        I couldn't reproduce the results he had unless I also didn't have a
                        nullity test - in which case you're comparing a non-error-checking
                        solution with an error-checking solution.

                        If your natural reaction is to say, "Ah, but as soon as you use the
                        reference" you need to then check what happens when you *do* use the
                        reference - and the answer is that the automatic nullity check which
                        happens there takes just as long as the casting in the first place. The
                        JIT is smart enough to know that if a local variable was null earlier
                        and isn't changed in between then and now, then it's not going to be
                        null now.

                        In other words, the only situation in which I can provoke the factor of
                        6 or so performance increase using "as" over casting is when you then
                        don't use the reference for a method call. I suppose in some
                        situations, when you're passing the local variable's value as a
                        parameter to another method, that might actually occur. I venture to
                        suggest that the number of times it's actually significant in the real
                        world is pretty close to zero.

                        In other words, I see no evidence that any choice regarding the use of
                        "as" vs casting should be made on performance grounds. If you still
                        think that performance is an issue, perhaps you could come up with a
                        real world scenario where it's significant.

                        --
                        Jon Skeet - <skeet@pobox.co m>
                        Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                        If replying to the group, please do not mail me too

                        Comment

                        • Frisky

                          #13
                          Re: What does it mean?

                          Intellectuals solve problems; geniuses prevent them. ~ Albert Einstein
                          "Jon Skeet [C# MVP]" <skeet@pobox.co m> wrote in message
                          news:MPG.1d16bd 43d99b79cc98c2e 3@msnews.micros oft.com...[color=blue]
                          > Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=green][color=darkred]
                          >> > BusinessType yourBusiness = (BusinessType) Factory.CreateO bject();
                          >> >
                          >> > I don't see the problem.[/color]
                          >>
                          >> <grin>Like I said you would say. (See below)</grin>
                          >>
                          >> Stick to the point. You should use "as" not casts whereever possible.
                          >> Where
                          >> your catch does not change which you should use.[/color]
                          >
                          > Yes it does. It makes a huge difference to the code. When you use as
                          > and test for nullity, you have to have that check *everywhere*. You
                          > gave sample code which mimicked that, but catching the exception - and
                          > unsurprisingly, it came out looking nasty. Change that to catching
                          > exceptions centrally, and you end up with *much* cleaner code.[/color]

                          I'm not getting huge difference; unless you mean how fast my code is, and
                          how easy to read it is, etc. :)

                          I don't have to check for nulls at all. If I don't it will still be at least
                          as fast or faster, and I will still throw.

                          But, if I do check for null, I don't have to check everywhere. I only have
                          to check where it counts. And I should be judicuous in this.

                          There is nothing nasty about that code using "as". Its short, easy to read,
                          and easy to understand. Actually, the code I showed made the example for
                          exceptions look ugly; in case in point where you do have to catch.

                          Also, you can't bubble everything up. Nor should you. The right object with
                          that responsibility should handle the exceptions he is responsible for.
                          Sometimes that means bubbling things up. Sometimes it means stop and pay
                          attention.

                          If you are refering to the single line of code that simply throws when
                          something goes wrong, I don't necessarily call that better. It comes at the
                          cost of increased complexity. I have now deferred that error to somewhere
                          else. But where? And, in how many places?
                          [color=blue][color=green]
                          >> But, if you would like to save yourself all of the exception processing,
                          >> a
                          >> simple check for null will do the trick. You code will be faster, and you
                          >> won't have to find another place to hide some exception code. You have
                          >> prevented the problem prior to it occurring.[/color]
                          >
                          > No, you haven't prevented the problem - you've just decided to
                          > understand the problem manually rather than automatically. I don't
                          > believe the code will be faster, either - why would it be? Both are
                          > doing the same thing, asking the runtime to do an "as" and then
                          > checking for nullity. (That's what a cast does internally.)[/color]

                          No, really I have decided to ignore the condition as not being a problem.
                          Just skip this code if its not relevant.

                          And the code will be faster. If you have a GUI that is firing tons of
                          exceptions, and those exceptions fire yet more messages, that guess what,
                          fire more exceptions, pretty soon you will be sucking wind.

                          If you look at the execution time, even the check alone (agreeably over very
                          large numbers) is serveral orders faster. And both will throw if you do not
                          check for null. Speaking distinctly as a comparison of casting to "as". But
                          if you don't throw, you just ignore, there is nothing left to do, no stack
                          to grab information on, no memory variables to create.
                          [color=blue][color=green]
                          >> In most instances, the exception, which must eventually be caught, will
                          >> end
                          >> up doing nothing. By bubbling the throw up, I just skipped the rest of
                          >> the
                          >> code in that method. So, if the rest of the code would have run, it won't
                          >> now. This may be what you wanted, but with the null check you can do
                          >> either.
                          >> And the null check costs virtually nothing.[/color]
                          >
                          > *If* you want the code to do nothing, yes, you should use "as". I find
                          > that case is much, much rarer than the case where you know that if
                          > there's an unexpected type there, it's due to a programming error, and
                          > you want to stop what you're doing as soon as possible.[/color]

                          But "as" is at least as fast, or faster than a cast. So, unless you mean to
                          cast, to get user conversions, or you have a value type, why used it? The
                          "as" is the straight up performance winner.
                          [color=blue][color=green][color=darkred]
                          >> > Casting and "as" are equally efficient when there aren't conversions
                          >> > involved, and that's decided at compile-time, not runtime.[/color]
                          >>
                          >> Are you conceeding my point?[/color]
                          >
                          > Not at all.[/color]

                          But you just said, "as" is equally fast in the worst case. In all other
                          cases, its faster. Did you look at that article on Code Project?
                          [color=blue][color=green]
                          >> So, "as" and cast are equivalent in the worst case, and "as" is
                          >> faster in the best case.[/color]
                          >
                          > In your best case, the operations are entirely distinct - they do
                          > different things. In your worst case, they're equivalent, and yet you
                          > claim above that it's faster.[/color]

                          And it is.
                          [color=blue][color=green]
                          >> Like I said, always use "as" unless you can't.[/color]
                          >
                          > If you like doing all your error handling manually - I don't.[/color]

                          You can still use exceptions.
                          [color=blue][color=green]
                          >> The code example given is most definitley a runtime type check. There is
                          >> know way the compiler can possibly know if the type of an item placed in
                          >> the
                          >> control array is a particular control. It only knows that it "is a"
                          >> Control.
                          >> This check and possible exception are generated at runtime.[/color]
                          >
                          > I don't think you read my post carefully enough. The compiler decides
                          > at compile-time whether or not it's just a cast, or whether it's a
                          > user-defined conversion.
                          >[color=green]
                          >> (Check out the article http://www.codeproject.com/csharp/csharpcasts.asp)
                          >> While I have not verified his results, my results were similar.[/color]
                          >
                          > I'll try it some time. Not that I believe the performance difference is
                          > ever going to be significant in many real applications - whereas the
                          > cost of failing to check for nullity *could* be significant, and all
                          > too easy to miss.[/color]

                          And while you may not find that the performance will pay off, it is better
                          to stick with high performance as a rule if you can.

                          And, I'm not saying you have to check for null if you use "as". You can
                          still stick with your current exception strategy.
                          [color=blue][color=green][color=darkred]
                          >> > If you genuinely don't know *and* you want to handle the situation
                          >> > where the result isn't a TextBox, sure. I would probably just throw an
                          >> > exception there anyway though, in most cases.[/color]
                          >>
                          >> There is nothing here that says you should not use "as".[/color]
                          >
                          > No, but there's nothing to say you shouldn't use a cast either - and
                          > the difference is between:
                          >
                          > TextBox tb = (TextBox) control;
                          >
                          > and:
                          >
                          > TextBox tb = control as TextBox;
                          > if (tb==null)
                          > {
                          > throw new SomeOtherExcept ion();
                          > }
                          >
                          > Do you really find the second code clearer?[/color]

                          Comparing Apples to Apples:

                          TextBox tb = (TextBox) control;

                          and:

                          TextBox tb = control as TextBox;

                          I find them equally readable.
                          [color=blue][color=green]
                          >> Again, as you
                          >> stated above, it is at least as efficient in the worst case. Oh, and if
                          >> you
                          >> don't check for null, it will still throw. But see below for why you
                          >> might
                          >> not want to do that.[/color]
                          >
                          > It will only throw in situations where you immediately use it though -
                          > which isn't always the case. What if you then pass it into a method
                          > which happily accepts nulls, but treats them differently? Very subtle
                          > bugs can be introduced that way...[/color]

                          I am not sure what you mean by this. ???

                          I only check for null where null values are not allowed. If a function takes
                          an object type, but does not allow nulls, it would assert. The code
                          provifing the null value would be in error.
                          [color=blue][color=green][color=darkred]
                          >> > No, because you're checking for null manually rather than letting the
                          >> > cast do the check for you and throw the exception appropriately. The
                          >> > important part of the bloat here is the source bloat - the extra check
                          >> > takes up precious space that could be getting on with what you actually
                          >> > want to be doing. That's the joy of using exceptions rather than return
                          >> > values - most of your actual code gets on with what you want to do,
                          >> > rather than error checking.[/color]
                          >>
                          >> Well, this of course depends on how you write your code. If you don't
                          >> mind
                          >> poor performance, throw all over the place. The combined "as" and null
                          >> check
                          >> are still way less impact to your code that the cast. And, when you do
                          >> throw, the cost is huge.[/color]
                          >
                          > It's not huge. It's about 100,000th of a second on my (not top of the
                          > range) laptop. That's not huge unless you're doing it time and time
                          > again, which indicates other problems in your code.[/color]

                          Or, you rely on lots of reentrant code, or are handling large quantities of
                          business rules and data, or etc. And performance overall does matter to me.
                          I would rather set me design goals based on using the faster of two options
                          unless there is a compelling reason not to. I see no compelling reason to
                          use a cast over "as". In light of that, I see performance as a compelling
                          reason to use "as" over a cast.

                          I simply add that even with the null check included, it is still faster than
                          the cast. Not that you have to do it that way. You can stick with your own
                          exception strategy.
                          [color=blue]
                          > I *do* throw all over the place - pretty much whenever I detect an
                          > error condition. Does the performance get hit? No, because there rarely
                          > *is* an error condition, and if there is, there's the hit of *one*
                          > exception, rather than hundreds of thousands. Like I've said,
                          > exceptions costing real life performance is more of a myth than reality
                          > in almost all applications.[/color]

                          Ok, now you are speaking my language. But, I thought I had said this in the
                          beinning anyway. It depends, are you expecting to throw, or are you
                          expecting not to throw.

                          And in general, my design is based on the approach you describe here. If you
                          never have an error, youv'e won the battle before it started.
                          [color=blue][color=green][color=darkred]
                          >> > ArrayList, actually. If you've got an actual array, I'd expect it to be
                          >> > the right type to start with.[/color]
                          >>
                          >> First, I do not know how you would know, based on the code here, exactly
                          >> how
                          >> this array was implemented. And if it was trully an array, what type it
                          >> was
                          >> defined on. An array does not have to be of your particular type. It
                          >> might
                          >> be of a base type or object type.[/color]
                          >
                          > Usually when I'm dealing with arrays, they're member variables of my
                          > own class, and they're usually of the right type. I rarely have to cast
                          > from arrays.[/color]

                          I use inheritence a lot. My arrays are not always so clean cut. But, if you
                          don't need to cast, you don't need "as" either.
                          [color=blue]
                          > <snip>
                          >[color=green][color=darkred]
                          >> > As for user conversions - as I said before, that's decided at compile-
                          >> > time, not run-time, so there's no bloat there, and the only times they
                          >> > *would* be used would be when I'd want them anyway. No new objects will
                          >> > be created when conversions aren't invoked.[/color]
                          >>
                          >> First, here is fundamental difference. I *don't want* to throw. If I am
                          >> going to throw, I know there is a *huge* overhead.[/color]
                          >
                          > Well, there's a ~0.001ms overhead. I don't think that's huge, unless
                          > you're planning to do it thousands of times - which basically isn't
                          > going to happen here.[/color]

                          For a single instruction on a 3.0 Ghz box that's huge. At that rate, I would
                          only be able to execute 1000 instuctions a second. But, my tests indicated
                          it was a higher hit than that.
                          [color=blue][color=green]
                          >> I need to be judicious
                          >> and make sure that throwing is correct for this particular problem.
                          >> Validating UI objects should almost always involve checking and not
                          >> throwing
                          >> because of performance. Also, again, I can continue with other updates to
                          >> the UI even if this one control is not behaving.[/color]
                          >
                          > Validating UI *input* should almost always involve checking (although
                          > not so much for performance reasons - a human in front of a UI
                          > certainly can't hit keys or move the mouse quickly enough to make it a
                          > problem to throw an exception every time they do so). Validating
                          > whether a control is actually what it should be? That doesn't need
                          > checking manually. If it's wrong, the code itself is screwed up.[/color]

                          Well that depends. We usually build dynamic screens. And, the users can drag
                          and drop UI components from one panel to the other. We mimic a lot of what
                          VS 2003 does but for our application.
                          [color=blue][color=green]
                          >> Second, there is no more code required to throw. When the "as" is
                          >> performed,
                          >> if it fails, you get null. If you attempt to use the null, as in the long
                          >> string of code originally shown, you will most certainly throw an
                          >> exception.[/color]
                          >
                          > In this particular case - what about when you're passing it elsewhere,
                          > or not using it immediately?[/color]

                          Depends on the elsewhere. But I don't tend to get values here for use
                          elsewhere. Unless elsewhere is another responsibility, but then again, if
                          its not responsible, that must make me, so I would need to do the
                          validation.
                          [color=blue][color=green]
                          >> I don't know how you would know based on the code shown if a user
                          >> conversion
                          >> exists or not.[/color]
                          >
                          > Because there's no defined conversion between Control and TextBox.
                          > Operators are overloaded, not overridden - it's a compile-time thing,
                          > not a run-time thing. If the actual control were some third-party
                          > control which didn't inherit from TextBox, but had a user-defined
                          > conversion to it, that wouldn't be performed in the casting case,
                          > because the compiler doesn't know about it at compile-time.[/color]

                          Quite. True, our code is down-casting our special textbox classes to one of
                          the classes in its lineage.

                          public static implicit operator TextBox(SuperDu perTextBox control)
                          {
                          // conversion code
                          }
                          [color=blue][color=green]
                          >> Are you saying because we havn't shown one. I have seen this
                          >> assumption bite many people. But, again, check out the article, and
                          >> perform
                          >> your own tests. I am not worried about bloat, but performance.[/color]
                          >
                          > I believe you are artificially worried about performance, perhaps
                          > partly based on previous bad experiences of very odd situations such as
                          > the one you mentioned where you didn't know what resources were in an
                          > assembly. (Any reason not to find them out using
                          > GetManifestReso urceNames? Better than asking speculatively in that
                          > situation, I'd say.)[/color]

                          I wish it had been that easy. But, performance if not artificial. And, the
                          systems I have written do not suffer from these issues. Sure, I base the
                          things I do on history. Experience has been a great teacher for me. Hence my
                          points.
                          [color=blue][color=green]
                          >> I don't think either of these methods bloats the code. One is just faster
                          >> than the other. (Not bloat; performance) And the slower casting method
                          >> does
                          >> not afford me any value add.[/color]
                          >
                          > Whereas it gives me the following benefits:
                          > 1) Shorter code where the main success path is clearer, not hidden by
                          > potential errors which can be handled (by throwing) by the runtime
                          >
                          > 2) Less room for accidentally forgetting the nullity check.[/color]

                          The code is not any shorter or longer. Cast versus "as". Not anymore clear.
                          In fact, hidden exception handling is who knows where. Its more comlpe.

                          Did you forget? I thought you wanted to throw? :) This is no different than
                          forgetting to add the hanlder code. Or anything else for that matter. You do
                          step through your code in the debugger when you write it don't you?
                          [color=blue][color=green][color=darkred]
                          >> >> BTW: Am I stepping on your turf or someting?
                          >> >
                          >> > Not at all. I just happen to disagree with you on code style.[/color]
                          >>
                          >> Just though I would ask. And, actually, the reason I asked is because of
                          >> the
                          >> reason you stated. You have disagreed with everything I wrote. But, I
                          >> have
                          >> noticed similar commnents in other articles in this group, which you
                          >> ignored. ???[/color]
                          >
                          > I don't respond to every article which I might disagree with - there
                          > wouldn't be time. You'll find I *do* tend to respond to people who
                          > claim there's a "huge overhead" in throwing exceptions though - they
                          > tend not to understand that exceptions can be thrown tens to hundreds
                          > of thousands of times per second in release mode (which is where
                          > performance matters). Once again, the actual cost of throwing an
                          > exception is almost *never* a bottleneck in real applications. Failure
                          > to check a return value is very easy to do though - and I'd always
                          > rather have a slight performance hit than a bug.
                          >[color=green]
                          >> I certainly do not mind that you and I going back and forth. This is
                          >> healthy, and both of us stand to learn something. Right?[/color]
                          >
                          > Absolutely.
                          >[color=green]
                          >> However, I would perfer a more contructive approach. A cooperative
                          >> attitude
                          >> would be nice. Even if you don't like my code style. I like it a lot. And
                          >> I
                          >> respect yours.[/color]
                          >
                          > I don't think I've been any less respectful to you than you have to me.[/color]

                          Not disrespect. I just found that you took exception (no pun intended) to my
                          comments in several post, yet steered clear of others. I just wondered if
                          you had something against me, or if you were after interllectual discussion.

                          You do seem adamant. But then again, so do I. :)

                          --
                          Frisky
                          [color=blue]
                          > --
                          > Jon Skeet - <skeet@pobox.co m>
                          > http://www.pobox.com/~skeet
                          > If replying to the group, please do not mail me too[/color]


                          Comment

                          • Jon Skeet [C# MVP]

                            #14
                            Re: What does it mean?

                            Frisky <Frisky_NOSPAM@ NorthPole.net> wrote:[color=blue][color=green]
                            > > Yes it does. It makes a huge difference to the code. When you use as
                            > > and test for nullity, you have to have that check *everywhere*. You
                            > > gave sample code which mimicked that, but catching the exception - and
                            > > unsurprisingly, it came out looking nasty. Change that to catching
                            > > exceptions centrally, and you end up with *much* cleaner code.[/color]
                            >
                            > I'm not getting huge difference; unless you mean how fast my code is, and
                            > how easy to read it is, etc. :)[/color]

                            We clearly have different ideas about readability. For me, making it
                            very easy to see the intended usual code path makes things more
                            readable than interspersing that with checking return values.
                            [color=blue]
                            > I don't have to check for nulls at all. If I don't it will still be at least
                            > as fast or faster, and I will still throw.[/color]

                            You'll still throw *sometimes*. Not always. It depends how you use the
                            variable.
                            [color=blue]
                            > But, if I do check for null, I don't have to check everywhere. I only have
                            > to check where it counts. And I should be judicuous in this.[/color]

                            Yup - you have to get it right, otherwise you could easily introduce a
                            bug. I prefer to let the runtime make the choice.
                            [color=blue]
                            > There is nothing nasty about that code using "as". Its short, easy to read,
                            > and easy to understand. Actually, the code I showed made the example for
                            > exceptions look ugly; in case in point where you do have to catch.[/color]

                            Which is very rare - you deliberately showed the worst possible case
                            for casting, and you're now asking me to compare that with the best
                            possible case for using "as" (where you don't even have to check the
                            result).
                            [color=blue]
                            > Also, you can't bubble everything up. Nor should you. The right object with
                            > that responsibility should handle the exceptions he is responsible for.
                            > Sometimes that means bubbling things up. Sometimes it means stop and pay
                            > attention.
                            >
                            > If you are refering to the single line of code that simply throws when
                            > something goes wrong, I don't necessarily call that better. It comes at the
                            > cost of increased complexity. I have now deferred that error to somewhere
                            > else. But where? And, in how many places?[/color]

                            Almost everywhere. Exceptions should usually be thrown when something
                            truly unexpected has happened - *especially* in the case of casting. If
                            there *is* a reasonable chance that the cast would fail (eg if you've
                            loaded a type whose name has been provided by the user) then that *is*
                            a good place to use "as" instead.
                            [color=blue][color=green]
                            > > No, you haven't prevented the problem - you've just decided to
                            > > understand the problem manually rather than automatically. I don't
                            > > believe the code will be faster, either - why would it be? Both are
                            > > doing the same thing, asking the runtime to do an "as" and then
                            > > checking for nullity. (That's what a cast does internally.)[/color]
                            >
                            > No, really I have decided to ignore the condition as not being a problem.
                            > Just skip this code if its not relevant.
                            >
                            > And the code will be faster. If you have a GUI that is firing tons of
                            > exceptions, and those exceptions fire yet more messages, that guess what,
                            > fire more exceptions, pretty soon you will be sucking wind.[/color]

                            But that just doesn't happen in reality. Unless you've got your code
                            hooked up very badly, you shouldn't be firing tons of exceptions
                            anyway. I've *never* suggested that exceptions should be thrown often
                            in terms of actual running code, just in terms of places in the code.
                            [color=blue]
                            > If you look at the execution time, even the check alone (agreeably over very
                            > large numbers) is serveral orders faster. And both will throw if you do not
                            > check for null. Speaking distinctly as a comparison of casting to "as". But
                            > if you don't throw, you just ignore, there is nothing left to do, no stack
                            > to grab information on, no memory variables to create.[/color]

                            No, "as" won't throw if you check for null and then use the value
                            somewhere that null is a valid value, but possibly not the one that you
                            actually want.
                            [color=blue][color=green]
                            > > *If* you want the code to do nothing, yes, you should use "as". I find
                            > > that case is much, much rarer than the case where you know that if
                            > > there's an unexpected type there, it's due to a programming error, and
                            > > you want to stop what you're doing as soon as possible.[/color]
                            >
                            > But "as" is at least as fast, or faster than a cast. So, unless you mean to
                            > cast, to get user conversions, or you have a value type, why used it? The
                            > "as" is the straight up performance winner.[/color]

                            No, it's the performance equal unless you decide not to check it, at
                            which point I believe it's a bug trap, deferring the point at which you
                            find out something has gone wrong.
                            [color=blue][color=green]
                            > > Not at all.[/color]
                            >
                            > But you just said, "as" is equally fast in the worst case. In all other
                            > cases, its faster. Did you look at that article on Code Project?[/color]

                            Yes. I actually *tried* it though. That article on Code Project left
                            out a lot of stuff (like code). Basically, unless you're using the
                            value from "as" in such a way that it *doesn't* show up errors
                            reasonably quickly, there's no real performance difference.
                            [color=blue][color=green]
                            > > In your best case, the operations are entirely distinct - they do
                            > > different things. In your worst case, they're equivalent, and yet you
                            > > claim above that it's faster.[/color]
                            >
                            > And it is.[/color]

                            Only if you don't check the value.
                            [color=blue][color=green][color=darkred]
                            > >> Like I said, always use "as" unless you can't.[/color]
                            > >
                            > > If you like doing all your error handling manually - I don't.[/color]
                            >
                            > You can still use exceptions.[/color]

                            And I will!
                            [color=blue][color=green][color=darkred]
                            > >> (Check out the article http://www.codeproject.com/csharp/csharpcasts.asp)
                            > >> While I have not verified his results, my results were similar.[/color]
                            > >
                            > > I'll try it some time. Not that I believe the performance difference is
                            > > ever going to be significant in many real applications - whereas the
                            > > cost of failing to check for nullity *could* be significant, and all
                            > > too easy to miss.[/color]
                            >
                            > And while you may not find that the performance will pay off, it is better
                            > to stick with high performance as a rule if you can.[/color]

                            Knuth disagrees.
                            [color=blue]
                            > And, I'm not saying you have to check for null if you use "as". You can
                            > still stick with your current exception strategy.[/color]

                            But to get the exception, you have to check for null or risk making the
                            eventual error harder to understand.
                            [color=blue][color=green]
                            > > No, but there's nothing to say you shouldn't use a cast either - and
                            > > the difference is between:
                            > >
                            > > TextBox tb = (TextBox) control;
                            > >
                            > > and:
                            > >
                            > > TextBox tb = control as TextBox;
                            > > if (tb==null)
                            > > {
                            > > throw new SomeOtherExcept ion();
                            > > }
                            > >
                            > > Do you really find the second code clearer?[/color]
                            >
                            > Comparing Apples to Apples:
                            >
                            > TextBox tb = (TextBox) control;
                            >
                            > and:
                            >
                            > TextBox tb = control as TextBox;
                            >
                            > I find them equally readable.[/color]

                            So do I - but the latter will mask any errors until later, unless you
                            have the check.
                            [color=blue][color=green]
                            > > It will only throw in situations where you immediately use it though -
                            > > which isn't always the case. What if you then pass it into a method
                            > > which happily accepts nulls, but treats them differently? Very subtle
                            > > bugs can be introduced that way...[/color]
                            >
                            > I am not sure what you mean by this. ???
                            >
                            > I only check for null where null values are not allowed. If a function takes
                            > an object type, but does not allow nulls, it would assert. The code
                            > provifing the null value would be in error.[/color]

                            But null could be an acceptable value for the method call, but one
                            which you (as the caller) never want to provide in this case. You also
                            lose the ability to distinguish between the original value being null
                            (which may be valid) and the original value being a reference to an
                            object of the wrong type.
                            [color=blue][color=green]
                            > > It's not huge. It's about 100,000th of a second on my (not top of the
                            > > range) laptop. That's not huge unless you're doing it time and time
                            > > again, which indicates other problems in your code.[/color]
                            >
                            > Or, you rely on lots of reentrant code, or are handling large quantities of
                            > business rules and data, or etc. And performance overall does matter to me.
                            > I would rather set me design goals based on using the faster of two options
                            > unless there is a compelling reason not to. I see no compelling reason to
                            > use a cast over "as". In light of that, I see performance as a compelling
                            > reason to use "as" over a cast.[/color]

                            Then we fundamentally disagree on what constitutes significant
                            performance. I believe that universally choosing "as" for performance
                            reasons when it *can* introduce bugs is a *really* bad idea.
                            [color=blue]
                            > I simply add that even with the null check included, it is still faster than
                            > the cast. Not that you have to do it that way. You can stick with your own
                            > exception strategy.[/color]

                            With the null check included, they're effectively the same speed in my
                            tests. Sometimes one version runs faster, sometimes the other.
                            [color=blue][color=green]
                            > > I *do* throw all over the place - pretty much whenever I detect an
                            > > error condition. Does the performance get hit? No, because there rarely
                            > > *is* an error condition, and if there is, there's the hit of *one*
                            > > exception, rather than hundreds of thousands. Like I've said,
                            > > exceptions costing real life performance is more of a myth than reality
                            > > in almost all applications.[/color]
                            >
                            > Ok, now you are speaking my language. But, I thought I had said this in the
                            > beinning anyway. It depends, are you expecting to throw, or are you
                            > expecting not to throw.[/color]

                            And I almost always want to throw in the very rare situation that I've
                            got an object of an unexpected type.
                            [color=blue]
                            > And in general, my design is based on the approach you describe here. If you
                            > never have an error, youv'e won the battle before it started.[/color]

                            Indeed. And if you *do* have an error, chances are you're not going to
                            get to the same situation thousands of times, and the performance hit
                            will be absolutely tiny.
                            [color=blue][color=green]
                            > > Usually when I'm dealing with arrays, they're member variables of my
                            > > own class, and they're usually of the right type. I rarely have to cast
                            > > from arrays.[/color]
                            >
                            > I use inheritence a lot. My arrays are not always so clean cut. But, if you
                            > don't need to cast, you don't need "as" either.[/color]

                            I find that inheritance is overrated. I only use it occasionally within
                            my own classes. It's invaluable when it's really required, but the
                            design requirements for a class which is meant to be inherited from are
                            much higher than other classes - the interaction between methods needs
                            to be fully documented as part of the interface, and then the
                            implementation has to pretty much stay the same. I prefer composition
                            over inheritance most of the time.
                            [color=blue][color=green][color=darkred]
                            > >> First, here is fundamental difference. I *don't want* to throw. If I am
                            > >> going to throw, I know there is a *huge* overhead.[/color]
                            > >
                            > > Well, there's a ~0.001ms overhead. I don't think that's huge, unless
                            > > you're planning to do it thousands of times - which basically isn't
                            > > going to happen here.[/color]
                            >
                            > For a single instruction on a 3.0 Ghz box that's huge. At that rate, I would
                            > only be able to execute 1000 instuctions a second.[/color]

                            No, you'd be able to execute nearly 1,000,000 instructions a second -
                            that figure was in milliseconds, not seconds. (It had a typo though - I
                            meant ~0.01ms, at which point you can execute it roughly 100,000 times
                            a second). The important thing is, however, that you won't be doing it
                            100,000 times a second.
                            [color=blue]
                            > But, my tests indicated it was a higher hit than that.[/color]

                            But your tests appear to have been run under the debugger.
                            [color=blue][color=green]
                            > > Validating UI *input* should almost always involve checking (although
                            > > not so much for performance reasons - a human in front of a UI
                            > > certainly can't hit keys or move the mouse quickly enough to make it a
                            > > problem to throw an exception every time they do so). Validating
                            > > whether a control is actually what it should be? That doesn't need
                            > > checking manually. If it's wrong, the code itself is screwed up.[/color]
                            >
                            > Well that depends. We usually build dynamic screens. And, the users can drag
                            > and drop UI components from one panel to the other. We mimic a lot of what
                            > VS 2003 does but for our application.[/color]

                            So you validate it once early on, and then you shouldn't need to do it
                            afterwards. Anyway, this sounds like a specialised situation which
                            wasn't indicated in the OP's post. I hope you'll agree that most UIs
                            *aren't* dynamic.
                            [color=blue][color=green]
                            > > In this particular case - what about when you're passing it elsewhere,
                            > > or not using it immediately?[/color]
                            >
                            > Depends on the elsewhere. But I don't tend to get values here for use
                            > elsewhere. Unless elsewhere is another responsibility, but then again, if
                            > its not responsible, that must make me, so I would need to do the
                            > validation.[/color]

                            That's a whole chain of reasoning I don't need to worry about. I like
                            not having to think, getting the error checking for free. The more I
                            have to think, the more chance I have to get it wrong.
                            [color=blue][color=green][color=darkred]
                            > >> I don't know how you would know based on the code shown if a user
                            > >> conversion
                            > >> exists or not.[/color]
                            > >
                            > > Because there's no defined conversion between Control and TextBox.
                            > > Operators are overloaded, not overridden - it's a compile-time thing,
                            > > not a run-time thing. If the actual control were some third-party
                            > > control which didn't inherit from TextBox, but had a user-defined
                            > > conversion to it, that wouldn't be performed in the casting case,
                            > > because the compiler doesn't know about it at compile-time.[/color]
                            >
                            > Quite. True, our code is down-casting our special textbox classes to one of
                            > the classes in its lineage.
                            >
                            > public static implicit operator TextBox(SuperDu perTextBox control)
                            > {
                            > // conversion code
                            > }[/color]

                            If SuperDuperTextB ox is actually a TextBox already, that's not a valid
                            operator. However, in the case that the OP posted, the compiler isn't
                            going to know that the cell's value is actually a SuperDuperTextB ox
                            anyway, so it can't use the user-defined conversion in the first place.
                            [color=blue][color=green]
                            > > I believe you are artificially worried about performance, perhaps
                            > > partly based on previous bad experiences of very odd situations such as
                            > > the one you mentioned where you didn't know what resources were in an
                            > > assembly. (Any reason not to find them out using
                            > > GetManifestReso urceNames? Better than asking speculatively in that
                            > > situation, I'd say.)[/color]
                            >
                            > I wish it had been that easy. But, performance if not artificial. And, the
                            > systems I have written do not suffer from these issues. Sure, I base the
                            > things I do on history. Experience has been a great teacher for me. Hence my
                            > points.[/color]

                            It sounds like experience *hasn't* been a great teacher though - it's
                            taught you to fear exceptions like they were the plague, bending code
                            out of shape to avoid throwing it, as in the case of the code you
                            showed for dealing with resources. The problem in that case wasn't that
                            you were throwing lots of exceptions, it was the *reason* you were
                            throwing lots of exceptions - namely that your resources were broken.
                            The fix for that isn't to ignore resources which should be there but
                            aren't, but to make sure that you only ask for what you need, and that
                            everything you need is present.

                            You've admitted that you've never run into a situation where decent
                            code has been significantly slowed down by exceptions, but you're still
                            coding as if they're about to slow your app down to a crawl at any
                            minute.
                            [color=blue][color=green][color=darkred]
                            > >> I don't think either of these methods bloats the code. One is just faster
                            > >> than the other. (Not bloat; performance) And the slower casting method
                            > >> does
                            > >> not afford me any value add.[/color]
                            > >
                            > > Whereas it gives me the following benefits:
                            > > 1) Shorter code where the main success path is clearer, not hidden by
                            > > potential errors which can be handled (by throwing) by the runtime
                            > >
                            > > 2) Less room for accidentally forgetting the nullity check.[/color]
                            >
                            > The code is not any shorter or longer. Cast versus "as". Not anymore clear.
                            > In fact, hidden exception handling is who knows where. Its more comlpe.[/color]

                            No, the exception handling is very predictable, whereas if you use
                            "as" it's somewhere separate from the change of reference type. It's
                            wherever it's first used - and *that's* "who knows where".
                            [color=blue]
                            > Did you forget? I thought you wanted to throw? :)[/color]

                            Which the cast does, if anything's wrong.
                            [color=blue]
                            > This is no different than
                            > forgetting to add the hanlder code. Or anything else for that matter. You do
                            > step through your code in the debugger when you write it don't you?[/color]

                            Nope. I try to avoid using the debugger whenever possible. I write unit
                            tests instead. Much more reliable. I regard having to resort to the
                            debugger as a partial admission of failure in the first place - it
                            means my code isn't clear enough to be able to spot a problem just from
                            the place that the unit test fails, or (worse) my unit tests aren't
                            good enough to spot a problem which has cropped up later on.
                            [color=blue][color=green]
                            > > I don't think I've been any less respectful to you than you have to me.[/color]
                            >
                            > Not disrespect. I just found that you took exception (no pun intended) to my
                            > comments in several post, yet steered clear of others. I just wondered if
                            > you had something against me, or if you were after interllectual discussion.
                            >
                            > You do seem adamant. But then again, so do I. :)[/color]

                            Like I said, I don't have time to read and respond to every post, but I
                            can point you in the directions of several times when I've had similar
                            "exceptions are hugely damaging to performance" discussions.

                            --
                            Jon Skeet - <skeet@pobox.co m>
                            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                            If replying to the group, please do not mail me too

                            Comment

                            Working...