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

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Data structure and exception

Data structure and exception

Scheduled Pinned Locked Moved C#
designalgorithmsdata-structureshelpquestion
6 Posts 3 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Super Lloyd
    wrote on last edited by
    #1

    I'm attempting to write a fairly complex data structure. One part of the complexity is that all 8 data operations it supports delegate some code to virtual method. This is by design because I want the user to subclass the data structure and be able to prevent changes to happen. and / or I want to notify observers. The unfortunate side effect is: it seems there are no simple way to have all user code run at the begining or at the end of the code. Hence some user code might be called in the middle of an operation and cause an unrecoverable error. (i.e. corrupt the data structure). Do you think it's acceptable? I am thinking there are 2 possibilities: 1. it's ok. Warn the user (in the documentation), these are critical data method, mess them, mess the data! 2. data structure should be fool proof, stack all user change in a class for this purpose and run them at the end what do you think?

    A I 2 Replies Last reply
    0
    • S Super Lloyd

      I'm attempting to write a fairly complex data structure. One part of the complexity is that all 8 data operations it supports delegate some code to virtual method. This is by design because I want the user to subclass the data structure and be able to prevent changes to happen. and / or I want to notify observers. The unfortunate side effect is: it seems there are no simple way to have all user code run at the begining or at the end of the code. Hence some user code might be called in the middle of an operation and cause an unrecoverable error. (i.e. corrupt the data structure). Do you think it's acceptable? I am thinking there are 2 possibilities: 1. it's ok. Warn the user (in the documentation), these are critical data method, mess them, mess the data! 2. data structure should be fool proof, stack all user change in a class for this purpose and run them at the end what do you think?

      A Offline
      A Offline
      Andrew Lygin
      wrote on last edited by
      #2

      You can use next template in your structure to recover your data when user code throws exception:

      public void SomeOperation()
      {
      try
      {
      SomeOperationBase();
      }
      catch(Exception)
      {
      // Recover your data here.
      // You can throw your own exception here (don't forget to set InnerException for it).
      // Or you can simply rethrow exception.
      throw;
      }
      }

      protected virtual void SomeOperationBase()
      {
      // Your code for SomeOperation() here.
      }

      Notice! 1. SomeOperation() is public and nonvirtual. 2. SomeOperationBase() is protected and virtual. You can also use this template to solve this problem:

      The unfortunate side effect is: it seems there are no simple way to have all user code run at the begining or at the end of the code.

      -- modified at 4:51 Sunday 9th July, 2006

      S 2 Replies Last reply
      0
      • A Andrew Lygin

        You can use next template in your structure to recover your data when user code throws exception:

        public void SomeOperation()
        {
        try
        {
        SomeOperationBase();
        }
        catch(Exception)
        {
        // Recover your data here.
        // You can throw your own exception here (don't forget to set InnerException for it).
        // Or you can simply rethrow exception.
        throw;
        }
        }

        protected virtual void SomeOperationBase()
        {
        // Your code for SomeOperation() here.
        }

        Notice! 1. SomeOperation() is public and nonvirtual. 2. SomeOperationBase() is protected and virtual. You can also use this template to solve this problem:

        The unfortunate side effect is: it seems there are no simple way to have all user code run at the begining or at the end of the code.

        -- modified at 4:51 Sunday 9th July, 2006

        S Offline
        S Offline
        Super Lloyd
        wrote on last edited by
        #3

        Thanks for answering! Doesn't work though! My Code is more like that:

        void ActionImpl() { /* ... */ }

        protected void Action(TextElement aParent)
        {
        foreach(TextElement child in this)
        child.Action(); // exception might happen in child too
        ActionImpl();
        NotifyAction(this); // <= potential user exception here
        }
        protected virtual void NotifyAction(TextElement aParent)
        {
        // nothing, up to the subclass
        // the subclass might throw an exception
        }

        One problem is the recovering action has user notification too! (in fact it just use the reverse operation). So the recovering could fail to. (and then I have 2 exception which I should report to the user... which might be confusing). So I decided I won't recover, I will just manage to have the data in a valid state, though neither the initial nor the expected final one. An other case is:

        protected void BigAction()
        {
        Action_1(); // subclass exception might happen here
        Action_2(); // subclass exception might happen here too
        }

        after Action_2() thrown an error I should undo Action_1(). But what if the undo throw an exception? It's all clear to me now. I should NOT recover. That was my mistake. I should report the exception straight away with as little change as possible. However I should, at least, ensure valid (even though unexpected) internal data.

        1 Reply Last reply
        0
        • A Andrew Lygin

          You can use next template in your structure to recover your data when user code throws exception:

          public void SomeOperation()
          {
          try
          {
          SomeOperationBase();
          }
          catch(Exception)
          {
          // Recover your data here.
          // You can throw your own exception here (don't forget to set InnerException for it).
          // Or you can simply rethrow exception.
          throw;
          }
          }

          protected virtual void SomeOperationBase()
          {
          // Your code for SomeOperation() here.
          }

          Notice! 1. SomeOperation() is public and nonvirtual. 2. SomeOperationBase() is protected and virtual. You can also use this template to solve this problem:

          The unfortunate side effect is: it seems there are no simple way to have all user code run at the begining or at the end of the code.

          -- modified at 4:51 Sunday 9th July, 2006

          S Offline
          S Offline
          Super Lloyd
          wrote on last edited by
          #4

          BTW my case is exactly the opposite. core work is NOT virtual. Unfortunately I have virtual "notification" method (or sometimes event, but that lead to the same logical problem). Which "might" throw an exception....

          1 Reply Last reply
          0
          • S Super Lloyd

            I'm attempting to write a fairly complex data structure. One part of the complexity is that all 8 data operations it supports delegate some code to virtual method. This is by design because I want the user to subclass the data structure and be able to prevent changes to happen. and / or I want to notify observers. The unfortunate side effect is: it seems there are no simple way to have all user code run at the begining or at the end of the code. Hence some user code might be called in the middle of an operation and cause an unrecoverable error. (i.e. corrupt the data structure). Do you think it's acceptable? I am thinking there are 2 possibilities: 1. it's ok. Warn the user (in the documentation), these are critical data method, mess them, mess the data! 2. data structure should be fool proof, stack all user change in a class for this purpose and run them at the end what do you think?

            I Offline
            I Offline
            Igor Sukhov
            wrote on last edited by
            #5

            If there's a possibility that the user's code might corrupt the data (which is likely to be true if the data is not a read-only and user has sufficient rights to change it) - provide some way to the [b]user[/b] to handle it. Don't try to recover data by your own means because obviously your code have no prior knowledge that might go wrong therefore there's no guaranty that you would be able to fix all the possible mess. If there's no guaranty - don't claim it. Let the user's code do all cleaning up/fixing job in a way he/she wants. One thing that might be usefull is ability of making a copy of data so the user could try again if bad things happened with the original data. If it pays to make a copy of the data before potentially dangerous operation - let user do the decision. The bottom line is - let the user decide is data was corrupted and if it was - let user's code recover from corruption. Best regards, ----------- Igor Sukhovhttp://sukhov.net

            S 1 Reply Last reply
            0
            • I Igor Sukhov

              If there's a possibility that the user's code might corrupt the data (which is likely to be true if the data is not a read-only and user has sufficient rights to change it) - provide some way to the [b]user[/b] to handle it. Don't try to recover data by your own means because obviously your code have no prior knowledge that might go wrong therefore there's no guaranty that you would be able to fix all the possible mess. If there's no guaranty - don't claim it. Let the user's code do all cleaning up/fixing job in a way he/she wants. One thing that might be usefull is ability of making a copy of data so the user could try again if bad things happened with the original data. If it pays to make a copy of the data before potentially dangerous operation - let user do the decision. The bottom line is - let the user decide is data was corrupted and if it was - let user's code recover from corruption. Best regards, ----------- Igor Sukhovhttp://sukhov.net

              S Offline
              S Offline
              Super Lloyd
              wrote on last edited by
              #6

              Exactly! That was one of my mistake!

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


              • Login

              • Don't have an account? Register

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