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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Prevent class member circular initialization?

Prevent class member circular initialization?

Scheduled Pinned Locked Moved C#
helpquestiondatabaseperformancetutorial
7 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    frattaro
    wrote on last edited by
    #1

    I'm not even sure how to ask the question, hah. I want two classes: User:

    public class User
    {
    private List groups = new List();
    public List Groups
    {
    get { return groups; }
    }
    //constructor selects groups from database, populates "groups" with new Group()
    }

    and Group:

    public class Group
    {
    private List users = new List();
    public List Users
    {
    get { return users; }
    }
    //constructor selects users from database, populates "users" with new User()
    }

    Say I have a Group "All Users". When I initialize a User I assume I'm going to get an out-of-memory error. Not that anyone would want to do this, but you should be able to do this:

    User u = new User();
    u.Groups["All Users"].Users[u.Username].Groups["All Users"].Users[u.Username] /*...*/;

    If anyone could help I'd appreciate it.

    L _ P 3 Replies Last reply
    0
    • F frattaro

      I'm not even sure how to ask the question, hah. I want two classes: User:

      public class User
      {
      private List groups = new List();
      public List Groups
      {
      get { return groups; }
      }
      //constructor selects groups from database, populates "groups" with new Group()
      }

      and Group:

      public class Group
      {
      private List users = new List();
      public List Users
      {
      get { return users; }
      }
      //constructor selects users from database, populates "users" with new User()
      }

      Say I have a Group "All Users". When I initialize a User I assume I'm going to get an out-of-memory error. Not that anyone would want to do this, but you should be able to do this:

      User u = new User();
      u.Groups["All Users"].Users[u.Username].Groups["All Users"].Users[u.Username] /*...*/;

      If anyone could help I'd appreciate it.

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

      you could solve that by postponing the creation of a list till you need it, like so:

      public class Group
      {
      private List users;
      public List Users
      {
      get {
      if (users==null) users=new List();
      return users;
      }
      }
      //constructor selects users from database, populates "users" with new User()
      }

      and optionally similar for user. That way, you only get the list when you actually use it. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

      Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

      D F 2 Replies Last reply
      0
      • F frattaro

        I'm not even sure how to ask the question, hah. I want two classes: User:

        public class User
        {
        private List groups = new List();
        public List Groups
        {
        get { return groups; }
        }
        //constructor selects groups from database, populates "groups" with new Group()
        }

        and Group:

        public class Group
        {
        private List users = new List();
        public List Users
        {
        get { return users; }
        }
        //constructor selects users from database, populates "users" with new User()
        }

        Say I have a Group "All Users". When I initialize a User I assume I'm going to get an out-of-memory error. Not that anyone would want to do this, but you should be able to do this:

        User u = new User();
        u.Groups["All Users"].Users[u.Username].Groups["All Users"].Users[u.Username] /*...*/;

        If anyone could help I'd appreciate it.

        _ Offline
        _ Offline
        _Erik_
        wrote on last edited by
        #3

        Make your groups collection in User class a singleton. It should be instantiated and populated just once.

        1 Reply Last reply
        0
        • L Luc Pattyn

          you could solve that by postponing the creation of a list till you need it, like so:

          public class Group
          {
          private List users;
          public List Users
          {
          get {
          if (users==null) users=new List();
          return users;
          }
          }
          //constructor selects users from database, populates "users" with new User()
          }

          and optionally similar for user. That way, you only get the list when you actually use it. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

          D Offline
          D Offline
          Dalek Dave
          wrote on last edited by
          #4

          That's pretty good. 5.

          ------------------------------------ I will never again mention that I was the poster of the One Millionth Lounge Post, nor that it was complete drivel. Dalek Dave CCC League Table Link CCC Link[^]

          1 Reply Last reply
          0
          • L Luc Pattyn

            you could solve that by postponing the creation of a list till you need it, like so:

            public class Group
            {
            private List users;
            public List Users
            {
            get {
            if (users==null) users=new List();
            return users;
            }
            }
            //constructor selects users from database, populates "users" with new User()
            }

            and optionally similar for user. That way, you only get the list when you actually use it. :)

            Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

            Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

            F Offline
            F Offline
            frattaro
            wrote on last edited by
            #5

            Took me a minute to understand but I get it. Thanks very much! [EDIT] and a few minutes later it seems all too obvious and I get mad for not thinking of it. :)

            L 1 Reply Last reply
            0
            • F frattaro

              Took me a minute to understand but I get it. Thanks very much! [EDIT] and a few minutes later it seems all too obvious and I get mad for not thinking of it. :)

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

              While it is technically correct, it does prevent the infinite recursion, this is still not the right way to handle things. 1. If you have a many-to-many relation like that, you should keep it outside both classes, i.e. the User class shouldn't automatically create or touch groups, and the Group class shouldn't create or touch users. You could give them a second constructor where a Group (or a User) is a parameter, basically saying "give me a new User and add him to this Group" for comfort, note this makes it all explicit. 2. If you want a single list that contains all objects of some class, the best way to do it is with a static list burried inside the class; then you should add them automatically.

              class User {
              private static List<User> users=new List<User>();

              public User() {
                  users.Add(this);
              }
              

              }

              You may then add a property that gets a read-only copy of the list of users, so your app can look at it. Warning: the list will grow; it will also remember User objects that no longer exist in your app, however by adding them to the list, they will never get collected. So you may want to use WeakReference instead; and maybe use a finalizer. etc. :)

              Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

              Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

              1 Reply Last reply
              0
              • F frattaro

                I'm not even sure how to ask the question, hah. I want two classes: User:

                public class User
                {
                private List groups = new List();
                public List Groups
                {
                get { return groups; }
                }
                //constructor selects groups from database, populates "groups" with new Group()
                }

                and Group:

                public class Group
                {
                private List users = new List();
                public List Users
                {
                get { return users; }
                }
                //constructor selects users from database, populates "users" with new User()
                }

                Say I have a Group "All Users". When I initialize a User I assume I'm going to get an out-of-memory error. Not that anyone would want to do this, but you should be able to do this:

                User u = new User();
                u.Groups["All Users"].Users[u.Username].Groups["All Users"].Users[u.Username] /*...*/;

                If anyone could help I'd appreciate it.

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

                In my opinion, a class shouldn't know anything about how, where, or whether it is stored anywhere -- that is not within its area of responsibility. Basically, a User may have a collection of Groups and a Group may have a collection of Users, but neither should be in charge of "getting" those collections. Some other class is responsible for knowing about the database and the relationship and reading and populating the collections. Here's a little something I just worked up to show how I might do it -- though I probably wouldn't :-D :

                public sealed class UserGroupManager
                {
                public UserGroupManager
                (
                Test DataContext
                )
                {
                this.Users = new System.Collections.Generic.HashSet<Test.User>() ;

                    this.Groups = new System.Collections.Generic.HashSet<Test.Group>() ;
                
                    foreach
                    (
                        Test.User user
                    in
                        DataContext.Users
                    )
                    {
                        foreach
                        (
                           Test.Group group
                        in
                            DataContext.ExecuteQuery<Test.Group>
                            (
                                @"SELECT \[Group\].\* FROM UserGroup INNER JOIN \[Group\] ON UserGroup.GroupID=\[Group\].ID WHERE UserGroup.UserID=?"
                            ,
                                user.ID
                            )
                        )
                        {
                            group.Users.Add ( user ) ;
                            user.Groups.Add ( group ) ;
                
                            this.Groups.Add ( group ) ;
                        }
                
                        this.Users.Add ( user ) ;
                    }
                
                    return ;
                }
                
                public readonly System.Collections.Generic.HashSet<Test.User> Users ;
                
                public readonly System.Collections.Generic.HashSet<Test.Group> Groups ;
                

                }

                (I've only been fiddling with Linq-to-SQL X| for the last few days.)

                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