C# equivalent to a smart pointer???

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

    C# equivalent to a smart pointer???

    I am looking at porting code from a C++ application to C#. This requires
    implementing data sharing functionality similar to what is provided by a
    smart pointer in C++. I have only recently begun to work in C# and am
    asking for suggestions/comments of how to implement a similar data sharing
    technique in C#.



    A C++ smart pointer can be used to share common information. For example,
    assume information managed by objects I1, I2, I3, ... Im are to be processed
    by objects P1, P2, P3, ... Pn. The total information contained by the 'Im'
    objects is considerable and it is not possible for each of the 'Pn' objects
    to phsyically duplicate the information contained in each of the 'Im'
    objects. However, if each of the 'Im' objects is a smart (i.e. referenced
    counted) pointer, then it is very easy for each 'Pn' object to get a
    reference to all of the 'Im' objects. As such, P1 can then process and
    delete it's copy of the 'Im' objects independently of when the other 'Pn-1'
    objects process and delete their 'Im' objects.



    My understanding is that the use of pointers in C# is strongly discouraged.
    The question then is there any other way for C# to implement data sharing
    functionality similar to that provided by smart pointers in C++?



    Thank you to all who respond,



    Ian


  • Tom Shelton

    #2
    Re: C# equivalent to a smart pointer???


    Ian wrote:
    I am looking at porting code from a C++ application to C#. This requires
    implementing data sharing functionality similar to what is provided by a
    smart pointer in C++. I have only recently begun to work in C# and am
    asking for suggestions/comments of how to implement a similar data sharing
    technique in C#.
    >
    >
    >
    A C++ smart pointer can be used to share common information. For example,
    assume information managed by objects I1, I2, I3, ... Im are to be processed
    by objects P1, P2, P3, ... Pn. The total information contained by the 'Im'
    objects is considerable and it is not possible for each of the 'Pn' objects
    to phsyically duplicate the information contained in each of the 'Im'
    objects. However, if each of the 'Im' objects is a smart (i.e. referenced
    counted) pointer, then it is very easy for each 'Pn' object to get a
    reference to all of the 'Im' objects. As such, P1 can then process and
    delete it's copy of the 'Im' objects independently of when the other 'Pn-1'
    objects process and delete their 'Im' objects.
    >
    >
    >
    My understanding is that the use of pointers in C# is strongly discouraged.
    The question then is there any other way for C# to implement data sharing
    functionality similar to that provided by smart pointers in C++?
    >
    >
    >
    Thank you to all who respond,
    >
    >
    >
    Ian
    Create a singleton object to manage the Im objects.

    --
    Tom Shelton

    Comment

    • Ian

      #3
      Re: C# equivalent to a smart pointer???

      >
      Create a singleton object to manage the Im objects.
      >
      --
      Tom Shelton
      >
      Hello Tom,

      The 'I' objects are dynamically created and added to a FIFO list. As the
      application runs, more of the 'I' objects are added to the FIFO list and
      those that have been processed by all of the 'P' objects are deleted. In
      addition, the 'P' objects run in different threads and the list of 'I'
      objects needs to be thread protected. In other words, the list of 'I' is
      constantly changing and the use of a smart pointer allows each of the 'P'
      objects to consider each 'I' object independently of the other 'Pn-1'
      objects. A singleton can be used to managed the list but each of the 'I'
      objects in the list must have smart-pointer equivalent functionality.

      Thanks,

      Ian



      Comment

      • Jon Slaughter

        #4
        Re: C# equivalent to a smart pointer???


        "Ian" <Ian00Bell@yahX X.comwrote in message
        news:vsPVg.4092 2$LH6.1135420@w agner.videotron .net...
        >I am looking at porting code from a C++ application to C#. This requires
        >implementing data sharing functionality similar to what is provided by a
        >smart pointer in C++. I have only recently begun to work in C# and am
        >asking for suggestions/comments of how to implement a similar data sharing
        >technique in C#.
        >
        >
        >
        A C++ smart pointer can be used to share common information. For example,
        assume information managed by objects I1, I2, I3, ... Im are to be
        processed by objects P1, P2, P3, ... Pn. The total information contained
        by the 'Im' objects is considerable and it is not possible for each of the
        'Pn' objects to phsyically duplicate the information contained in each of
        the 'Im' objects. However, if each of the 'Im' objects is a smart (i.e.
        referenced counted) pointer, then it is very easy for each 'Pn' object to
        get a reference to all of the 'Im' objects. As such, P1 can then process
        and delete it's copy of the 'Im' objects independently of when the other
        'Pn-1' objects process and delete their 'Im' objects.
        >
        >
        >
        My understanding is that the use of pointers in C# is strongly
        discouraged. The question then is there any other way for C# to implement
        data sharing functionality similar to that provided by smart pointers in
        C++?
        >
        >
        >
        Thank you to all who respond,
        >
        >
        I'm not sure if there is an "equivilent " of smart pointers in managed C#
        since there isn't really an equivilent of pointers. But you can use
        unmanaged to use pointers and might be able to create a smart pointer class
        to do what you want.

        A site that discusses this:




        I think though what you want is a reference type in C#:



        I'm just starting out in C# so I can't really tell you exactly what you need
        but I would bet that where theres a will theres a way. (you could always
        wrap unmangaged C++ smart pointer in a managed C# class I guess)

        Jon


        Comment

        • Jon Slaughter

          #5
          Re: C# equivalent to a smart pointer???


          "Ian" <Ian00Bell@yahX X.comwrote in message
          news:H1QVg.4178 4$LH6.1158479@w agner.videotron .net...

          >Create a singleton object to manage the Im objects.
          >>
          >--
          >Tom Shelton
          >>
          >
          Hello Tom,
          >
          The 'I' objects are dynamically created and added to a FIFO list. As the
          application runs, more of the 'I' objects are added to the FIFO list and
          those that have been processed by all of the 'P' objects are deleted. In
          addition, the 'P' objects run in different threads and the list of 'I'
          objects needs to be thread protected. In other words, the list of 'I' is
          constantly changing and the use of a smart pointer allows each of the 'P'
          objects to consider each 'I' object independently of the other 'Pn-1'
          objects. A singleton can be used to managed the list but each of the
          'I' objects in the list must have smart-pointer equivalent functionality.
          >
          Thanks,
          >
          Ian
          >
          >
          >
          You also might want to check out this thread:



          It discusses the garbage collector which seems to have similar functionality
          or can be used to do what you want.


          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: C# equivalent to a smart pointer???

            Ian <Ian00Bell@yahX X.comwrote:
            I am looking at porting code from a C++ application to C#. This requires
            implementing data sharing functionality similar to what is provided by a
            smart pointer in C++. I have only recently begun to work in C# and am
            asking for suggestions/comments of how to implement a similar data sharing
            technique in C#.
            Unless you need to release resources other than memory, a reference
            type will give you the semantics you need. When nothing "live" has a
            reference to an object, it is eligible for garbage collection next time
            the garbage collector runs (in the generation containing the object).

            --
            Jon Skeet - <skeet@pobox.co m>
            http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
            If replying to the group, please do not mail me too

            Comment

            • Ian

              #7
              Re: C# equivalent to a smart pointer???


              "Jon Slaughter" <Jon_Slaughter@ Hotmail.comwrot e in message
              news:12ifn1baa1 cu0d7@corp.supe rnews.com...
              >
              I think though what you want is a reference type in C#:
              >

              >
              Jon
              >
              Hello Jon,

              Yes, I have looked at the reference type in C# but this raises several
              questions:

              1) How can 2 or more objects obtain a reference to a list of common objects.
              For example, how can objects P1, P2 and P3 obtain a reference to common
              objects I1, I2, I3, ... Im?

              2) Objects P1, P2 and P3 process the 'Im' objects asyncrhonously. So P2
              and P3 can continue to process the 'Im' objects for some time after P1 has
              deleted it's reference to the 'Im' objects. In addition, the 'Pn' objects
              can be updated with newly created 'I' objects (i.e. a FIFO). This is easily
              managed using a list of smart-pointers

              What is interesting is that the C# 'String' implement this type of
              functionality. The C# String is a reference type that is allocated on the
              heap. Assigning one string variable to another string variable creates 2
              references to the same string in memory. The question is, does C# do the
              same thing for a managed object that is referenced by 2 or more variables?

              Ian


              Comment

              • Peter Duniho

                #8
                Re: C# equivalent to a smart pointer???

                "Ian" <Ian00Bell@yahX X.comwrote in message
                news:vsPVg.4092 2$LH6.1135420@w agner.videotron .net...
                [...]
                My understanding is that the use of pointers in C# is strongly
                discouraged. The question then is there any other way for C# to implement
                data sharing functionality similar to that provided by smart pointers in
                C++?
                I can't say that I'm completely clear on your particular use of the phrase
                "smart pointer". However, in my experience this usually just means a
                ref-counted pointer, in the manner used by COM. There is even an ATL type,
                the CComPtr, that is commonly used to wrap the COM AddRef/Release
                functionality.

                If I understand your question correctly, this is essentially what you are
                looking for. And if that's the case, then C# provides this functionality
                innately through the reference type. For example:

                class I1
                {
                }

                class M1
                {
                public I1 _i1;
                }

                class M2
                {
                public I1 _i1;
                }

                void example()
                {
                M1 m1 = new M1();
                M2 m2 = new M2();
                I1 i1 = new I1(); // first reference to the I1 instance

                m1._i1 = i1; // second reference to the I1 instance
                m2._i1 = i1; // a third reference to the same I1 instance
                m1._i1 = null; // now there's only two references again
                m2._i1 = null;

                // now there's only one reference to the I1 instance, the
                // the local variable. Once we return out of this function,
                // there will be no references and the I1 object itself will
                // eventually be disposed of/freed/deleted/whatever through
                // garbage collection
                }

                If you need for the object to be freed on a more timely basis than the
                garbage collector will do it, then there are ways to explicitly dispose the
                object. This is usually only necessary when the object itself maintains
                some kind of reference to an unmanaged object (which usually actually means
                a reference to some lower-level OS object that is in short supply). See
                "using" and "Dispose" for more details.

                As you can see from the above, unless you have a need to retrieve your "I"
                objects later, you don't even need to maintain a global list of them. You
                can create one, add it to all the "P" objects that need to process it, and
                when they are all done, the "I" object will go away.

                If, for some reason, you need to manipulate the "I" objects at some later
                time, or need a way of knowing when an "I" object has been processed by all
                of the "P" objects, you would need to maintain an extra reference somewhere
                (perhaps in a List<Tobject), and/or (depending on the exact need) add some
                kind of "processing owner" count independent of the total references that
                when is reduced back to zero (by the last processing thread that handles the
                object) whatever processing needed at the end is done.

                Whether this final action on the object can be done while disposing the
                object, or you need the extra "processing monitoring" functionality added, I
                can't say. Your problem description is too vague for us to know. (As far
                as I know, it's not a good idea to do anything particularly expensive while
                disposing an object...but if any final processing just involves minimal,
                cleanup-like behavior you could just handle it while disposing). But
                hopefully the above gives you a starting point, and you can figure out for
                yourself what the correct approach is.

                Pete


                Comment

                • Ian

                  #9
                  Re: C# equivalent to a smart pointer???


                  "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
                  news:MPG.1f91ef 0e6563b82298d51 d@msnews.micros oft.com...
                  Unless you need to release resources other than memory, a reference
                  type will give you the semantics you need. When nothing "live" has a
                  reference to an object, it is eligible for garbage collection next time
                  the garbage collector runs (in the generation containing the object).
                  >
                  --
                  Wonderful! Have a great weekend.

                  Ian


                  Comment

                  • Ian

                    #10
                    Re: C# equivalent to a smart pointer???

                    "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
                    news:12ifpobes4 bq12e@corp.supe rnews.com...
                    "Ian" <Ian00Bell@yahX X.comwrote in message
                    news:vsPVg.4092 2$LH6.1135420@w agner.videotron .net...
                    >[...]
                    >My understanding is that the use of pointers in C# is strongly
                    >discouraged. The question then is there any other way for C# to implement
                    >data sharing functionality similar to that provided by smart pointers in
                    >C++?
                    >
                    ....
                    >
                    Whether this final action on the object can be done while disposing the
                    object, or you need the extra "processing monitoring" functionality added,
                    I can't say. Your problem description is too vague for us to know. (As
                    far as I know, it's not a good idea to do anything particularly expensive
                    while disposing an object...but if any final processing just involves
                    minimal, cleanup-like behavior you could just handle it while disposing).
                    But hopefully the above gives you a starting point, and you can figure out
                    for yourself what the correct approach is.
                    >
                    Pete
                    >
                    Hello Peter,

                    Many thanks for the example. I think both you and Jon Skeet have provided
                    the answer to my questions. Your code illustrates clearly the concept I was
                    asking about. Many thanks for taking the time to answer my question. I so
                    content I think I'll even take the day off :)

                    hope you have as good a weekend as you have made mine

                    Ian


                    Comment

                    • Peter Duniho

                      #11
                      Re: C# equivalent to a smart pointer???

                      "Ian" <Ian00Bell@yahX X.comwrote in message
                      news:CtRVg.4384 8$LH6.1207696@w agner.videotron .net...
                      Yes, I have looked at the reference type in C# but this raises several
                      questions:
                      Perhaps you can clarify what "smart pointer" implementation you're using.
                      The questions you raise are not related to any "smart pointer"
                      implementation I'm aware of. Knowing exactly what "smart pointer" you're
                      talking about would go a long way to helping people give you the advice
                      you're looking for.

                      In particular:
                      1) How can 2 or more objects obtain a reference to a list of common
                      objects. For example, how can objects P1, P2 and P3 obtain a reference to
                      common objects I1, I2, I3, ... Im?
                      That depends on how you create the objects and intend to reference them.
                      But the mechanism is independent of any "smart pointer" behavior I know of.
                      That is, I've never heard of a "smart pointer" implementation that by itself
                      manages what objects reference what other objects or how those references
                      are maintained. You still need other code to deal with who owns what. All
                      "smart pointers" generally do is keep track of how many references exist,
                      and whether it's time to delete an object.
                      2) Objects P1, P2 and P3 process the 'Im' objects asyncrhonously. So P2
                      and P3 can continue to process the 'Im' objects for some time after P1 has
                      deleted it's reference to the 'Im' objects. In addition, the 'Pn' objects
                      can be updated with newly created 'I' objects (i.e. a FIFO). This is
                      easily managed using a list of smart-pointers
                      Likewise, "smart pointer" implementations that I'm aware of don't in and of
                      themselves deal with thread synchronization . Some may protect the reference
                      counting itself, but otherwise operations on the object are not
                      automatically thread-safe. You still need to lock the necessary aspects of
                      an object that may be accessed by more than one thread at a time, to ensure
                      that only one thread is actually manipulating those aspects at any given
                      time.

                      If, on the other hand, all that you mean is that each thread (corresponding
                      to one "P" object perhaps?) maintains its own queue of processable objects,
                      then this is simple to implement using any "smart pointer" implementation,
                      including the C# reference type. You still need to protect access to the
                      queues (presumably you've either got one thread adding "I" objects to each
                      "P" object's queue, or you've got each "P" object pulling "I" objects from a
                      shared queue, or some combination thereof), but handling the lifetime of the
                      object is dealt with automatically through the use of the C# reference type.
                      Just set the reference to null, or remove it from your queue, or whatever
                      method you need in order to "forget" the reference, and C# will eventually
                      delete the object.
                      What is interesting is that the C# 'String' implement this type of
                      functionality. The C# String is a reference type that is allocated on the
                      heap. Assigning one string variable to another string variable creates 2
                      references to the same string in memory. The question is, does C# do the
                      same thing for a managed object that is referenced by 2 or more variables?
                      Yes...C# deals with all reference type objects the same way it deals with
                      the String object. There's nothing special about the String object in this
                      respect...all reference type objects are handled this way.

                      Pete


                      Comment

                      • Jon Skeet [C# MVP]

                        #12
                        Re: C# equivalent to a smart pointer???

                        Ian <Ian00Bell@yahX X.comwrote:
                        Yes, I have looked at the reference type in C# but this raises several
                        questions:
                        >
                        1) How can 2 or more objects obtain a reference to a list of common objects.
                        For example, how can objects P1, P2 and P3 obtain a reference to common
                        objects I1, I2, I3, ... Im?
                        Well, P1-P3 would often be passed references to I1-Im in methods, or
                        they'd all have a reference to a common list which contained those
                        references.
                        2) Objects P1, P2 and P3 process the 'Im' objects asyncrhonously. So P2
                        and P3 can continue to process the 'Im' objects for some time after P1 has
                        deleted it's reference to the 'Im' objects. In addition, the 'Pn' objects
                        can be updated with newly created 'I' objects (i.e. a FIFO). This is easily
                        managed using a list of smart-pointers
                        In C# there's no idea of "deleting" a reference - you don't need to
                        worry about something being freed too early.
                        What is interesting is that the C# 'String' implement this type of
                        functionality. The C# String is a reference type that is allocated on the
                        heap. Assigning one string variable to another string variable creates 2
                        references to the same string in memory. The question is, does C# do the
                        same thing for a managed object that is referenced by 2 or more
                        variables?
                        *All* reference types are allocated on the heap. See
                        Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.


                        --
                        Jon Skeet - <skeet@pobox.co m>
                        http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                        If replying to the group, please do not mail me too

                        Comment

                        • Peter Duniho

                          #13
                          Re: C# equivalent to a smart pointer???

                          "Ian" <Ian00Bell@yahX X.comwrote in message
                          news:H5SVg.4421 0$LH6.1227626@w agner.videotron .net...
                          Many thanks for the example. I think both you and Jon Skeet have provided
                          the answer to my questions. Your code illustrates clearly the concept I
                          was asking about. Many thanks for taking the time to answer my question.
                          I so content I think I'll even take the day off :)
                          >
                          hope you have as good a weekend as you have made mine
                          Glad we could help. Sorry if my other post rambles off into something you
                          didn't have a problem with. When I wrote it, I hadn't seen that you already
                          felt your question was answered. :)

                          I would like to add a couple of comments to the concept of references here,
                          because I personally find them non-intuitive, and in fact only came across
                          the issues by accident. IMHO, they're especially important to someone
                          coming at this from a C background (as many of us do), because the behavior
                          deviates from what we've learned to expect. Hopefully this will make some
                          good reading for you once you're back at work on Monday. :)

                          Both issues relate to (overly, IMHO) aggressive optimizations of local
                          variables on the part of the C# compiler. One of the issues, I learned
                          about in this newsgroup. The basic idea is that the compiler may detect
                          that a local variable appears to be an alias for some other variable, and
                          optimize out the use of the local altogether. For example:

                          {
                          Object objLocal = objGlobal;

                          if (objLocal != null)
                          {
                          objLocal.DoSome thing();
                          }
                          }

                          In this example, you might naively think that because you've stored the
                          reference locally, that even if the objGlobal reference is set to null,
                          you're okay. Apparently that's an incorrect assumption in some cases, and
                          if it's possible for the objGlobal variable to get set to null after the
                          if() statement (say, by a different thread), the line that actually calls
                          the DoSomething() method could wind up resolving to
                          "objGlobal.DoSo mething()" and cause a null-reference exception when it
                          executes.

                          The second issue I came across reading documentation on an entirely
                          different issue. It showed up in some sample code in the documentation.
                          The issue is that the lifetime of a local variable is NOT determined by
                          scope. The compiler will treat the object essentially as out-of-scope even
                          within the same scope if it's not used in any code past a certain point.
                          For example:

                          {
                          Object objLocal = new Object();

                          objLocal.DoSome thing();

                          PointA:

                          // some other code goes here, but nothing that uses
                          // the objLocal variable

                          PointB:
                          }

                          If you're accustomed to C++ style smart pointers, you're probably using a
                          class that releases a reference in its destructor, which is run as you leave
                          the scope. That is, at "PointB:". However, in C# it turns out that the
                          compiler may consider the end of the lifetime of the object to occur at
                          "PointA:", because there are no more uses of the local past that point.

                          This shouldn't normally be a problem, but there do turn out to be situations
                          in which an object is "busy" even though the code has continued and it
                          doesn't appear that the object is being referenced any more. The specific
                          example I saw in the documentation was the use of the System.Timers.T imer
                          object, where the object behavior continues even after the last line of code
                          where the object is used.

                          In most cases, if your object is still "busy" even though it's not
                          referenced locally past a certain point, it likely has been referenced
                          somewhere else and won't be garbage-collected. But you should be aware of
                          the possibility...i f the only reference maintained to an object is local,
                          AND the object is not explicitly referenced beyond a certain point within
                          the current scope, AND it turns out that the object is still "active" beyond
                          that certain point, you need to add an explicit reference at the end of the
                          scope (or wherever you need to live until), to keep the object alive until
                          that point. The GC class even includes a GC.KeepAlive() method for this
                          very purpose...it doesn't do anything except give you an explicit reference
                          in the code so that the compiler doesn't cause your object to be discarded
                          too early.

                          IMHO, these are BOTH really dangerous, non-intuitive aspects of the design
                          of C#. As much as I'm enjoying C# generally, I am running into things like
                          this every now and then that belie the apparent goal of C# and .NET to make
                          code MORE robust and with FEWER defects. IMHO, stuff like this represents
                          exactly the sort of non-intuitive, optimization-related behavior that trips
                          up programmers in other languages and should have been left out of a
                          language and environment in which the goal is (should be) to make things
                          safer and less buggy.

                          If it weren't for the fact that I know some person related to the C# team at
                          Microsoft is sure to defend these behaviors as "by design", I'd go ahead and
                          call them bugs. But at the least, they are hazards and poorly-documented
                          ones at that.

                          Pete


                          Comment

                          • Jon Skeet [C# MVP]

                            #14
                            Re: C# equivalent to a smart pointer???

                            Peter Duniho <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote:
                            I would like to add a couple of comments to the concept of references here,
                            because I personally find them non-intuitive, and in fact only came across
                            the issues by accident. IMHO, they're especially important to someone
                            coming at this from a C background (as many of us do), because the behavior
                            deviates from what we've learned to expect. Hopefully this will make some
                            good reading for you once you're back at work on Monday. :)
                            >
                            Both issues relate to (overly, IMHO) aggressive optimizations of local
                            variables on the part of the C# compiler. One of the issues, I learned
                            about in this newsgroup. The basic idea is that the compiler may detect
                            that a local variable appears to be an alias for some other variable, and
                            optimize out the use of the local altogether. For example:
                            >
                            {
                            Object objLocal = objGlobal;
                            >
                            if (objLocal != null)
                            {
                            objLocal.DoSome thing();
                            }
                            }
                            >
                            In this example, you might naively think that because you've stored the
                            reference locally, that even if the objGlobal reference is set to null,
                            you're okay. Apparently that's an incorrect assumption in some cases, and
                            if it's possible for the objGlobal variable to get set to null after the
                            if() statement (say, by a different thread), the line that actually calls
                            the DoSomething() method could wind up resolving to
                            "objGlobal.DoSo mething()" and cause a null-reference exception when it
                            executes.
                            I should point out that this is only my understanding based on an MS
                            blog entry. At some point I hope to correspond with the author to check
                            that that really *is* the case.
                            The second issue I came across reading documentation on an entirely
                            different issue. It showed up in some sample code in the documentation.
                            The issue is that the lifetime of a local variable is NOT determined by
                            scope. The compiler will treat the object essentially as out-of-scope even
                            within the same scope if it's not used in any code past a certain point.
                            This one I think is more reasonable - it's really just a case of
                            getting out of a C++ idiom which doesn't apply in .NET. Note that it's
                            not C# which is doing the work here - it's the JIT. Basically, one
                            shouldn't be using scope to determine the lifetime of an object.

                            I should say, however, that the case you've given isn't the strangest
                            one at all (although I usually see questions relating to it with Mutex
                            instead of Timer). What's weirder is when the finalizer for an object
                            can be invoked *while a method is still running in that object*.

                            I've had a go at hooking up an example to show it, and I can't at the
                            minute, but the main thing is that the GC is free to collect an object
                            when it knows that no thread is going to access the member variables of
                            the object again. Just to scare you a bit more :)

                            --
                            Jon Skeet - <skeet@pobox.co m>
                            http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                            If replying to the group, please do not mail me too

                            Comment

                            • Peter Duniho

                              #15
                              Re: C# equivalent to a smart pointer???

                              "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
                              news:MPG.1f9221 a01e65ae0698d51 f@msnews.micros oft.com...
                              [...]
                              >In this example, you might naively think that because you've stored the
                              >reference locally, that even if the objGlobal reference is set to null,
                              >you're okay. Apparently that's an incorrect assumption in some cases,
                              >and
                              >if it's possible for the objGlobal variable to get set to null after the
                              >if() statement (say, by a different thread), the line that actually calls
                              >the DoSomething() method could wind up resolving to
                              >"objGlobal.DoS omething()" and cause a null-reference exception when it
                              >executes.
                              >
                              I should point out that this is only my understanding based on an MS
                              blog entry. At some point I hope to correspond with the author to check
                              that that really *is* the case.
                              Okay...that would be nice. I know that I was a bit taken aback when I saw
                              that here. It would be good to know just how scared I need to be. :)
                              >The second issue I came across reading documentation on an entirely
                              >different issue. It showed up in some sample code in the documentation.
                              >The issue is that the lifetime of a local variable is NOT determined by
                              >scope. The compiler will treat the object essentially as out-of-scope
                              >even
                              >within the same scope if it's not used in any code past a certain point.
                              >
                              This one I think is more reasonable - it's really just a case of
                              getting out of a C++ idiom which doesn't apply in .NET. Note that it's
                              not C# which is doing the work here - it's the JIT.
                              Thanks. I know...I need to get in the habit of distinguishing the two
                              compilers. I realize the issue isn't specific to C#, but it *is* a compiler
                              optimization. Just not a language-specific one.
                              Basically, one
                              shouldn't be using scope to determine the lifetime of an object.
                              Well, obviously not. :) I'm just saying that it's not entirely obvious
                              when one shows up to write .NET code that this issue exists.

                              If I take the time to think about it, I understand that when you have the
                              concept of reference types that .NET has, the idea of lifetime has nothing
                              to do with scope. A good example of this is that since references assigned
                              within a specific scope can easily escape that scope. Objects can easily
                              live longer than the scope in which they are created. But IMHO it's a more
                              significant leap for traditionally-trained programmers to think of objects
                              as being able to disappear even *before* the scope in which they were
                              defined and referenced is exited.

                              I realize that the main problem is that traditionally-trained programmers
                              were trained in an environment that didn't natively support anything like
                              the concept of .NET reference types. I also realize that there are
                              languages that predate C# that do support this concept (but are not
                              languages that most programmers are exposed to in anything more than a
                              cursory way).

                              But still, it's not like it would have been all that difficult for the .NET
                              definition to maintain a reference to an object throughout the existence of
                              a scope in which a variable exists that references that object, it would not
                              affect performance in the vast majority of cases, and in the few instances
                              in which the behavior is desirable for some reason, it would be trivial to
                              explicitly obtain that behavior. Basically, this is a solution without a
                              problem.

                              I understand why, from a theoretical design standpoint, it is just as
                              legitimate to define the lifetime of a reference to an object as being
                              directly related to the code that could explicitly reference that object,
                              rather than related to the scope of a variable defined to reference that
                              object. But it's still a relatively non-intuitive behavior IMHO, it could
                              easily have been defined differently, and the way it's been defined results
                              in a greater likelihood of incorrect code than the other way would have.

                              IMHO, theory is just fine until it conflicts with getting correct code.
                              Correct code should be the higher priority, and I think this is especially
                              true in the context of .NET.

                              Sorry for the essay...but I still think this particular behavior is odd and
                              unwarranted. And of course, it led to the quite ungainly GC.KeepAlive
                              method. Never mind the potential for creating bugs, it makes some code ugly
                              too. :)
                              I should say, however, that the case you've given isn't the strangest
                              one at all (although I usually see questions relating to it with Mutex
                              instead of Timer). What's weirder is when the finalizer for an object
                              can be invoked *while a method is still running in that object*.
                              Yes, that's pretty weird. One hopes that in that case, the method running
                              isn't actually going to reference the object itself. Please tell me that's
                              so. :)
                              I've had a go at hooking up an example to show it, and I can't at the
                              minute, but the main thing is that the GC is free to collect an object
                              when it knows that no thread is going to access the member variables of
                              the object again. Just to scare you a bit more :)
                              Thanks. That's all I need. :)

                              As far as coming up with an example, if I understand the nature of the issue
                              correctly all that would be required is to have a method on an object
                              executing asynchronously, that is time-consuming enough to give the GC time
                              to run, and which does not actually refer to the object itself once the
                              time-consuming part has begun. I'd think a method that just has a call to
                              Sleep with a long duration, where the object references are all removed
                              before the Sleep expires, would demonstrate what you're talking about.

                              Of course, that assumes I know what you're talking about. I might not. :)

                              Pete


                              Comment

                              Working...