List or Dictionary of Objects inside Class





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







6















A friend and I (both new in programming) were arguing if it was wise to include a Dictionary inside a Class that contains all instances of that class.



I say that is better that the dictionary is in the main instead in the class itself.



I have no strong reasons to say why , but i've never seen classes keeping records of the objects that has created.



Could you give me pros and cons of each approach?



Thanks in advance.



A:



    class Table
{
public static Dictionary<int,Table> Tables = new Dictionary<int, Table>();
...
public table (int ID) // constructor
{
...
Tables.Add(ID,this);
}
}


B:



     class Program
{
public Dictionary<int,Table> Tables = new Dictionary<int, Table>();
static void Main(string args)
{
...
Table A = new Table (10);
Tables.Add(10,A);
}
}









share|improve this question























  • Side note: do not expose fields but readonly properties: what if I assign null to Tables? E.g. Table.Tables = null;

    – Dmitry Bychenko
    1 hour ago













  • @DmitryBychenko readonly is not good enough for this because you can still call any method from the Dictionary. The proper way to do this is to make it private and only interact with it using class methods.

    – Chris Rollins
    1 hour ago






  • 1





    @Chris Rollins: sure; at least expose Tables as IReadOnlyDictionary<int, Table> readonly property.

    – Dmitry Bychenko
    1 hour ago











  • @DmitryBychenko that's a clever approach

    – Chris Rollins
    1 hour ago






  • 1





    Have you considered using MemoryCache instead?

    – mjwills
    1 hour ago


















6















A friend and I (both new in programming) were arguing if it was wise to include a Dictionary inside a Class that contains all instances of that class.



I say that is better that the dictionary is in the main instead in the class itself.



I have no strong reasons to say why , but i've never seen classes keeping records of the objects that has created.



Could you give me pros and cons of each approach?



Thanks in advance.



A:



    class Table
{
public static Dictionary<int,Table> Tables = new Dictionary<int, Table>();
...
public table (int ID) // constructor
{
...
Tables.Add(ID,this);
}
}


B:



     class Program
{
public Dictionary<int,Table> Tables = new Dictionary<int, Table>();
static void Main(string args)
{
...
Table A = new Table (10);
Tables.Add(10,A);
}
}









share|improve this question























  • Side note: do not expose fields but readonly properties: what if I assign null to Tables? E.g. Table.Tables = null;

    – Dmitry Bychenko
    1 hour ago













  • @DmitryBychenko readonly is not good enough for this because you can still call any method from the Dictionary. The proper way to do this is to make it private and only interact with it using class methods.

    – Chris Rollins
    1 hour ago






  • 1





    @Chris Rollins: sure; at least expose Tables as IReadOnlyDictionary<int, Table> readonly property.

    – Dmitry Bychenko
    1 hour ago











  • @DmitryBychenko that's a clever approach

    – Chris Rollins
    1 hour ago






  • 1





    Have you considered using MemoryCache instead?

    – mjwills
    1 hour ago














6












6








6


1






A friend and I (both new in programming) were arguing if it was wise to include a Dictionary inside a Class that contains all instances of that class.



I say that is better that the dictionary is in the main instead in the class itself.



I have no strong reasons to say why , but i've never seen classes keeping records of the objects that has created.



Could you give me pros and cons of each approach?



Thanks in advance.



A:



    class Table
{
public static Dictionary<int,Table> Tables = new Dictionary<int, Table>();
...
public table (int ID) // constructor
{
...
Tables.Add(ID,this);
}
}


B:



     class Program
{
public Dictionary<int,Table> Tables = new Dictionary<int, Table>();
static void Main(string args)
{
...
Table A = new Table (10);
Tables.Add(10,A);
}
}









share|improve this question














A friend and I (both new in programming) were arguing if it was wise to include a Dictionary inside a Class that contains all instances of that class.



I say that is better that the dictionary is in the main instead in the class itself.



I have no strong reasons to say why , but i've never seen classes keeping records of the objects that has created.



Could you give me pros and cons of each approach?



Thanks in advance.



A:



    class Table
{
public static Dictionary<int,Table> Tables = new Dictionary<int, Table>();
...
public table (int ID) // constructor
{
...
Tables.Add(ID,this);
}
}


B:



     class Program
{
public Dictionary<int,Table> Tables = new Dictionary<int, Table>();
static void Main(string args)
{
...
Table A = new Table (10);
Tables.Add(10,A);
}
}






c#






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 hours ago









Mariano ValenzuelaMariano Valenzuela

4815




4815













  • Side note: do not expose fields but readonly properties: what if I assign null to Tables? E.g. Table.Tables = null;

    – Dmitry Bychenko
    1 hour ago













  • @DmitryBychenko readonly is not good enough for this because you can still call any method from the Dictionary. The proper way to do this is to make it private and only interact with it using class methods.

    – Chris Rollins
    1 hour ago






  • 1





    @Chris Rollins: sure; at least expose Tables as IReadOnlyDictionary<int, Table> readonly property.

    – Dmitry Bychenko
    1 hour ago











  • @DmitryBychenko that's a clever approach

    – Chris Rollins
    1 hour ago






  • 1





    Have you considered using MemoryCache instead?

    – mjwills
    1 hour ago



















  • Side note: do not expose fields but readonly properties: what if I assign null to Tables? E.g. Table.Tables = null;

    – Dmitry Bychenko
    1 hour ago













  • @DmitryBychenko readonly is not good enough for this because you can still call any method from the Dictionary. The proper way to do this is to make it private and only interact with it using class methods.

    – Chris Rollins
    1 hour ago






  • 1





    @Chris Rollins: sure; at least expose Tables as IReadOnlyDictionary<int, Table> readonly property.

    – Dmitry Bychenko
    1 hour ago











  • @DmitryBychenko that's a clever approach

    – Chris Rollins
    1 hour ago






  • 1





    Have you considered using MemoryCache instead?

    – mjwills
    1 hour ago

















Side note: do not expose fields but readonly properties: what if I assign null to Tables? E.g. Table.Tables = null;

– Dmitry Bychenko
1 hour ago







Side note: do not expose fields but readonly properties: what if I assign null to Tables? E.g. Table.Tables = null;

– Dmitry Bychenko
1 hour ago















@DmitryBychenko readonly is not good enough for this because you can still call any method from the Dictionary. The proper way to do this is to make it private and only interact with it using class methods.

– Chris Rollins
1 hour ago





@DmitryBychenko readonly is not good enough for this because you can still call any method from the Dictionary. The proper way to do this is to make it private and only interact with it using class methods.

– Chris Rollins
1 hour ago




1




1





@Chris Rollins: sure; at least expose Tables as IReadOnlyDictionary<int, Table> readonly property.

– Dmitry Bychenko
1 hour ago





@Chris Rollins: sure; at least expose Tables as IReadOnlyDictionary<int, Table> readonly property.

– Dmitry Bychenko
1 hour ago













@DmitryBychenko that's a clever approach

– Chris Rollins
1 hour ago





@DmitryBychenko that's a clever approach

– Chris Rollins
1 hour ago




1




1





Have you considered using MemoryCache instead?

– mjwills
1 hour ago





Have you considered using MemoryCache instead?

– mjwills
1 hour ago












5 Answers
5






active

oldest

votes


















2














It mostly depends on your needs and your architectural/design preferences.



Having the dictionary inside your class makes all class-related logic nicely encapsulated. That way, you can hide the (static) dictionary from the class users and have it managed by your class internally.



Having the dictionary outside your class makes the mechanism flexible in other ways. You can manage multiple different dictionaries for your class instances (for multiple purposes), for instance. Or you can just leave such a dictionary away if you don't need it in a specific solution environment.



IMHO, there are no strict guidelines that tell you that you should or shouldn't do something specific. Just be creative. As long as the end result is clear, maintainable, extendable etc. the sky is the limit.






share|improve this answer































    1














    Well, A version means that you can't have two Table with a same ID.



    using System.Collections.Concurrent;

    ...

    public class Table {
    //DONE: Do not expose fields but readonly properties
    //DONE: Keep static (i.e. global) members (fields, properties, methods) being thread safe
    private static ConcurrentDictionary<int, Table> s_Tables =
    new ConcurrentDictionary<int, Table>();

    public Table(int ID) {
    s_Tables.Add(ID, this);
    }

    //DONE: All we expose is thead safe read-only version of the dictionary
    public static IReadOnlyDictionary<int, Table> Tables = s_Tables;
    }


    When B version means that you can well have several Program each of them have their own Tables and that's why ID is not globaly unique:



    public class Program {
    //DONE: Do not expose fields but readonly properties
    private Dictionary<int,Table> m_Tables = new Dictionary<int, Table>();

    public Program() {
    Table A = new Table (10);
    m_Tables.Add(10,A);

    ...
    }

    //DONE: All we expose is read-only version of the dictionary
    public IReadOnlyDictionary<int, Table> Tables = m_Tables;
    }

    ...

    //DONE: please, do not cram all the logic into `Main`,
    // have a special classes business logic (Program) and entry point
    public static class EntryPoint {
    static void Main(string args) {
    Program program = new Program();

    ...
    }
    }


    Since in your original code you have static void Main in Program class it's efficiently singleton, so it seems, version A is preferable: all about Table are within Table class; you can't occasionaly create a second instance of Table with same ID






    share|improve this answer

































      0














      Approach A. If all instances of a class should be tracked then it should be an automatic feature of the class which can be implemented using a static dictionary. The dictionary should be private so that other classes cannot modify it. This gives you a guarantee that the dictionary will be correct.



      However, this is not a good technique for beginner programmers because it prevents the objects from being cleaned up by garbage collection. This means you have to manually decide when the objects should be released, at which time you remove them from the dictionary. You could implement the iDisposable interface for this. Usually it's best to use a using block with it, but sometimes you will need to find another way to manage the lifetime of the objects.



      Approach B is fine for a small program, but it does not have any advantages either. In a larger program it will be hard to manage and prone to mistakes. You may forget to add an object, or you may have some code incorrectly add or remove an object, or some code may assume an object is there when it was removed, etc...






      share|improve this answer































        0














        It's nothing wrong with any concepts. You have to decide whether caching is part of the design (A) or is an option of a consumer layer (B).



        If it is a built-in feature I would slightly modify approach A:



        public class Table
        {
        // cache is private so it cannot be manipulated from outside
        private static Dictionary<int,Table> tables = new Dictionary<int, Table>();

        // constructor is private so Table can be created by the GetTable factory method
        private Table(int id)
        {
        //...
        }

        // the factory method that transparently returns the table either from cache or by creating one
        public static Table GetTable(int id)
        {
        if (tables.TryGetValue(id, out Table result))
        return result;
        result = new Table(id);
        tables[id] = result;
        return result;
        }
        }





        share|improve this answer



















        • 1





          The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

          – Dmitry Bychenko
          1 hour ago











        • Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

          – taffer
          1 hour ago





















        0














        A:
        pros: none
        cons:




        • it is not the responsibility of class to track its instances (see SRP)


        • non-thread-safe (see ConcurrentDictionary)



        B:
        pros:




        • class is not burdened excess responsibilities that out its scope


        cons:




        • 'tracking'-code should be encapsulated to separate class that be responsible for creating instances, tracking them, managing time life strategy, etc (factory may fit for that)

        • non-thread-safe


        As mentioned above If you need to cache some items then use the MemoryCache.






        share|improve this answer


























          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55898506%2flist-or-dictionary-of-objects-inside-class%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          It mostly depends on your needs and your architectural/design preferences.



          Having the dictionary inside your class makes all class-related logic nicely encapsulated. That way, you can hide the (static) dictionary from the class users and have it managed by your class internally.



          Having the dictionary outside your class makes the mechanism flexible in other ways. You can manage multiple different dictionaries for your class instances (for multiple purposes), for instance. Or you can just leave such a dictionary away if you don't need it in a specific solution environment.



          IMHO, there are no strict guidelines that tell you that you should or shouldn't do something specific. Just be creative. As long as the end result is clear, maintainable, extendable etc. the sky is the limit.






          share|improve this answer




























            2














            It mostly depends on your needs and your architectural/design preferences.



            Having the dictionary inside your class makes all class-related logic nicely encapsulated. That way, you can hide the (static) dictionary from the class users and have it managed by your class internally.



            Having the dictionary outside your class makes the mechanism flexible in other ways. You can manage multiple different dictionaries for your class instances (for multiple purposes), for instance. Or you can just leave such a dictionary away if you don't need it in a specific solution environment.



            IMHO, there are no strict guidelines that tell you that you should or shouldn't do something specific. Just be creative. As long as the end result is clear, maintainable, extendable etc. the sky is the limit.






            share|improve this answer


























              2












              2








              2







              It mostly depends on your needs and your architectural/design preferences.



              Having the dictionary inside your class makes all class-related logic nicely encapsulated. That way, you can hide the (static) dictionary from the class users and have it managed by your class internally.



              Having the dictionary outside your class makes the mechanism flexible in other ways. You can manage multiple different dictionaries for your class instances (for multiple purposes), for instance. Or you can just leave such a dictionary away if you don't need it in a specific solution environment.



              IMHO, there are no strict guidelines that tell you that you should or shouldn't do something specific. Just be creative. As long as the end result is clear, maintainable, extendable etc. the sky is the limit.






              share|improve this answer













              It mostly depends on your needs and your architectural/design preferences.



              Having the dictionary inside your class makes all class-related logic nicely encapsulated. That way, you can hide the (static) dictionary from the class users and have it managed by your class internally.



              Having the dictionary outside your class makes the mechanism flexible in other ways. You can manage multiple different dictionaries for your class instances (for multiple purposes), for instance. Or you can just leave such a dictionary away if you don't need it in a specific solution environment.



              IMHO, there are no strict guidelines that tell you that you should or shouldn't do something specific. Just be creative. As long as the end result is clear, maintainable, extendable etc. the sky is the limit.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 1 hour ago









              Bart HoflandBart Hofland

              77249




              77249

























                  1














                  Well, A version means that you can't have two Table with a same ID.



                  using System.Collections.Concurrent;

                  ...

                  public class Table {
                  //DONE: Do not expose fields but readonly properties
                  //DONE: Keep static (i.e. global) members (fields, properties, methods) being thread safe
                  private static ConcurrentDictionary<int, Table> s_Tables =
                  new ConcurrentDictionary<int, Table>();

                  public Table(int ID) {
                  s_Tables.Add(ID, this);
                  }

                  //DONE: All we expose is thead safe read-only version of the dictionary
                  public static IReadOnlyDictionary<int, Table> Tables = s_Tables;
                  }


                  When B version means that you can well have several Program each of them have their own Tables and that's why ID is not globaly unique:



                  public class Program {
                  //DONE: Do not expose fields but readonly properties
                  private Dictionary<int,Table> m_Tables = new Dictionary<int, Table>();

                  public Program() {
                  Table A = new Table (10);
                  m_Tables.Add(10,A);

                  ...
                  }

                  //DONE: All we expose is read-only version of the dictionary
                  public IReadOnlyDictionary<int, Table> Tables = m_Tables;
                  }

                  ...

                  //DONE: please, do not cram all the logic into `Main`,
                  // have a special classes business logic (Program) and entry point
                  public static class EntryPoint {
                  static void Main(string args) {
                  Program program = new Program();

                  ...
                  }
                  }


                  Since in your original code you have static void Main in Program class it's efficiently singleton, so it seems, version A is preferable: all about Table are within Table class; you can't occasionaly create a second instance of Table with same ID






                  share|improve this answer






























                    1














                    Well, A version means that you can't have two Table with a same ID.



                    using System.Collections.Concurrent;

                    ...

                    public class Table {
                    //DONE: Do not expose fields but readonly properties
                    //DONE: Keep static (i.e. global) members (fields, properties, methods) being thread safe
                    private static ConcurrentDictionary<int, Table> s_Tables =
                    new ConcurrentDictionary<int, Table>();

                    public Table(int ID) {
                    s_Tables.Add(ID, this);
                    }

                    //DONE: All we expose is thead safe read-only version of the dictionary
                    public static IReadOnlyDictionary<int, Table> Tables = s_Tables;
                    }


                    When B version means that you can well have several Program each of them have their own Tables and that's why ID is not globaly unique:



                    public class Program {
                    //DONE: Do not expose fields but readonly properties
                    private Dictionary<int,Table> m_Tables = new Dictionary<int, Table>();

                    public Program() {
                    Table A = new Table (10);
                    m_Tables.Add(10,A);

                    ...
                    }

                    //DONE: All we expose is read-only version of the dictionary
                    public IReadOnlyDictionary<int, Table> Tables = m_Tables;
                    }

                    ...

                    //DONE: please, do not cram all the logic into `Main`,
                    // have a special classes business logic (Program) and entry point
                    public static class EntryPoint {
                    static void Main(string args) {
                    Program program = new Program();

                    ...
                    }
                    }


                    Since in your original code you have static void Main in Program class it's efficiently singleton, so it seems, version A is preferable: all about Table are within Table class; you can't occasionaly create a second instance of Table with same ID






                    share|improve this answer




























                      1












                      1








                      1







                      Well, A version means that you can't have two Table with a same ID.



                      using System.Collections.Concurrent;

                      ...

                      public class Table {
                      //DONE: Do not expose fields but readonly properties
                      //DONE: Keep static (i.e. global) members (fields, properties, methods) being thread safe
                      private static ConcurrentDictionary<int, Table> s_Tables =
                      new ConcurrentDictionary<int, Table>();

                      public Table(int ID) {
                      s_Tables.Add(ID, this);
                      }

                      //DONE: All we expose is thead safe read-only version of the dictionary
                      public static IReadOnlyDictionary<int, Table> Tables = s_Tables;
                      }


                      When B version means that you can well have several Program each of them have their own Tables and that's why ID is not globaly unique:



                      public class Program {
                      //DONE: Do not expose fields but readonly properties
                      private Dictionary<int,Table> m_Tables = new Dictionary<int, Table>();

                      public Program() {
                      Table A = new Table (10);
                      m_Tables.Add(10,A);

                      ...
                      }

                      //DONE: All we expose is read-only version of the dictionary
                      public IReadOnlyDictionary<int, Table> Tables = m_Tables;
                      }

                      ...

                      //DONE: please, do not cram all the logic into `Main`,
                      // have a special classes business logic (Program) and entry point
                      public static class EntryPoint {
                      static void Main(string args) {
                      Program program = new Program();

                      ...
                      }
                      }


                      Since in your original code you have static void Main in Program class it's efficiently singleton, so it seems, version A is preferable: all about Table are within Table class; you can't occasionaly create a second instance of Table with same ID






                      share|improve this answer















                      Well, A version means that you can't have two Table with a same ID.



                      using System.Collections.Concurrent;

                      ...

                      public class Table {
                      //DONE: Do not expose fields but readonly properties
                      //DONE: Keep static (i.e. global) members (fields, properties, methods) being thread safe
                      private static ConcurrentDictionary<int, Table> s_Tables =
                      new ConcurrentDictionary<int, Table>();

                      public Table(int ID) {
                      s_Tables.Add(ID, this);
                      }

                      //DONE: All we expose is thead safe read-only version of the dictionary
                      public static IReadOnlyDictionary<int, Table> Tables = s_Tables;
                      }


                      When B version means that you can well have several Program each of them have their own Tables and that's why ID is not globaly unique:



                      public class Program {
                      //DONE: Do not expose fields but readonly properties
                      private Dictionary<int,Table> m_Tables = new Dictionary<int, Table>();

                      public Program() {
                      Table A = new Table (10);
                      m_Tables.Add(10,A);

                      ...
                      }

                      //DONE: All we expose is read-only version of the dictionary
                      public IReadOnlyDictionary<int, Table> Tables = m_Tables;
                      }

                      ...

                      //DONE: please, do not cram all the logic into `Main`,
                      // have a special classes business logic (Program) and entry point
                      public static class EntryPoint {
                      static void Main(string args) {
                      Program program = new Program();

                      ...
                      }
                      }


                      Since in your original code you have static void Main in Program class it's efficiently singleton, so it seems, version A is preferable: all about Table are within Table class; you can't occasionaly create a second instance of Table with same ID







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 1 hour ago

























                      answered 1 hour ago









                      Dmitry BychenkoDmitry Bychenko

                      113k10100142




                      113k10100142























                          0














                          Approach A. If all instances of a class should be tracked then it should be an automatic feature of the class which can be implemented using a static dictionary. The dictionary should be private so that other classes cannot modify it. This gives you a guarantee that the dictionary will be correct.



                          However, this is not a good technique for beginner programmers because it prevents the objects from being cleaned up by garbage collection. This means you have to manually decide when the objects should be released, at which time you remove them from the dictionary. You could implement the iDisposable interface for this. Usually it's best to use a using block with it, but sometimes you will need to find another way to manage the lifetime of the objects.



                          Approach B is fine for a small program, but it does not have any advantages either. In a larger program it will be hard to manage and prone to mistakes. You may forget to add an object, or you may have some code incorrectly add or remove an object, or some code may assume an object is there when it was removed, etc...






                          share|improve this answer




























                            0














                            Approach A. If all instances of a class should be tracked then it should be an automatic feature of the class which can be implemented using a static dictionary. The dictionary should be private so that other classes cannot modify it. This gives you a guarantee that the dictionary will be correct.



                            However, this is not a good technique for beginner programmers because it prevents the objects from being cleaned up by garbage collection. This means you have to manually decide when the objects should be released, at which time you remove them from the dictionary. You could implement the iDisposable interface for this. Usually it's best to use a using block with it, but sometimes you will need to find another way to manage the lifetime of the objects.



                            Approach B is fine for a small program, but it does not have any advantages either. In a larger program it will be hard to manage and prone to mistakes. You may forget to add an object, or you may have some code incorrectly add or remove an object, or some code may assume an object is there when it was removed, etc...






                            share|improve this answer


























                              0












                              0








                              0







                              Approach A. If all instances of a class should be tracked then it should be an automatic feature of the class which can be implemented using a static dictionary. The dictionary should be private so that other classes cannot modify it. This gives you a guarantee that the dictionary will be correct.



                              However, this is not a good technique for beginner programmers because it prevents the objects from being cleaned up by garbage collection. This means you have to manually decide when the objects should be released, at which time you remove them from the dictionary. You could implement the iDisposable interface for this. Usually it's best to use a using block with it, but sometimes you will need to find another way to manage the lifetime of the objects.



                              Approach B is fine for a small program, but it does not have any advantages either. In a larger program it will be hard to manage and prone to mistakes. You may forget to add an object, or you may have some code incorrectly add or remove an object, or some code may assume an object is there when it was removed, etc...






                              share|improve this answer













                              Approach A. If all instances of a class should be tracked then it should be an automatic feature of the class which can be implemented using a static dictionary. The dictionary should be private so that other classes cannot modify it. This gives you a guarantee that the dictionary will be correct.



                              However, this is not a good technique for beginner programmers because it prevents the objects from being cleaned up by garbage collection. This means you have to manually decide when the objects should be released, at which time you remove them from the dictionary. You could implement the iDisposable interface for this. Usually it's best to use a using block with it, but sometimes you will need to find another way to manage the lifetime of the objects.



                              Approach B is fine for a small program, but it does not have any advantages either. In a larger program it will be hard to manage and prone to mistakes. You may forget to add an object, or you may have some code incorrectly add or remove an object, or some code may assume an object is there when it was removed, etc...







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 1 hour ago









                              Chris RollinsChris Rollins

                              31228




                              31228























                                  0














                                  It's nothing wrong with any concepts. You have to decide whether caching is part of the design (A) or is an option of a consumer layer (B).



                                  If it is a built-in feature I would slightly modify approach A:



                                  public class Table
                                  {
                                  // cache is private so it cannot be manipulated from outside
                                  private static Dictionary<int,Table> tables = new Dictionary<int, Table>();

                                  // constructor is private so Table can be created by the GetTable factory method
                                  private Table(int id)
                                  {
                                  //...
                                  }

                                  // the factory method that transparently returns the table either from cache or by creating one
                                  public static Table GetTable(int id)
                                  {
                                  if (tables.TryGetValue(id, out Table result))
                                  return result;
                                  result = new Table(id);
                                  tables[id] = result;
                                  return result;
                                  }
                                  }





                                  share|improve this answer



















                                  • 1





                                    The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

                                    – Dmitry Bychenko
                                    1 hour ago











                                  • Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

                                    – taffer
                                    1 hour ago


















                                  0














                                  It's nothing wrong with any concepts. You have to decide whether caching is part of the design (A) or is an option of a consumer layer (B).



                                  If it is a built-in feature I would slightly modify approach A:



                                  public class Table
                                  {
                                  // cache is private so it cannot be manipulated from outside
                                  private static Dictionary<int,Table> tables = new Dictionary<int, Table>();

                                  // constructor is private so Table can be created by the GetTable factory method
                                  private Table(int id)
                                  {
                                  //...
                                  }

                                  // the factory method that transparently returns the table either from cache or by creating one
                                  public static Table GetTable(int id)
                                  {
                                  if (tables.TryGetValue(id, out Table result))
                                  return result;
                                  result = new Table(id);
                                  tables[id] = result;
                                  return result;
                                  }
                                  }





                                  share|improve this answer



















                                  • 1





                                    The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

                                    – Dmitry Bychenko
                                    1 hour ago











                                  • Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

                                    – taffer
                                    1 hour ago
















                                  0












                                  0








                                  0







                                  It's nothing wrong with any concepts. You have to decide whether caching is part of the design (A) or is an option of a consumer layer (B).



                                  If it is a built-in feature I would slightly modify approach A:



                                  public class Table
                                  {
                                  // cache is private so it cannot be manipulated from outside
                                  private static Dictionary<int,Table> tables = new Dictionary<int, Table>();

                                  // constructor is private so Table can be created by the GetTable factory method
                                  private Table(int id)
                                  {
                                  //...
                                  }

                                  // the factory method that transparently returns the table either from cache or by creating one
                                  public static Table GetTable(int id)
                                  {
                                  if (tables.TryGetValue(id, out Table result))
                                  return result;
                                  result = new Table(id);
                                  tables[id] = result;
                                  return result;
                                  }
                                  }





                                  share|improve this answer













                                  It's nothing wrong with any concepts. You have to decide whether caching is part of the design (A) or is an option of a consumer layer (B).



                                  If it is a built-in feature I would slightly modify approach A:



                                  public class Table
                                  {
                                  // cache is private so it cannot be manipulated from outside
                                  private static Dictionary<int,Table> tables = new Dictionary<int, Table>();

                                  // constructor is private so Table can be created by the GetTable factory method
                                  private Table(int id)
                                  {
                                  //...
                                  }

                                  // the factory method that transparently returns the table either from cache or by creating one
                                  public static Table GetTable(int id)
                                  {
                                  if (tables.TryGetValue(id, out Table result))
                                  return result;
                                  result = new Table(id);
                                  tables[id] = result;
                                  return result;
                                  }
                                  }






                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered 1 hour ago









                                  taffertaffer

                                  8,81121536




                                  8,81121536








                                  • 1





                                    The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

                                    – Dmitry Bychenko
                                    1 hour ago











                                  • Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

                                    – taffer
                                    1 hour ago
















                                  • 1





                                    The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

                                    – Dmitry Bychenko
                                    1 hour ago











                                  • Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

                                    – taffer
                                    1 hour ago










                                  1




                                  1





                                  The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

                                  – Dmitry Bychenko
                                  1 hour ago





                                  The next step is to make tables being thread safe (e.g. with a help of ConcurrentDictionary<int, Table>)

                                  – Dmitry Bychenko
                                  1 hour ago













                                  Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

                                  – taffer
                                  1 hour ago







                                  Yes, if the real-life scenario demands it, it can be polished. In that case the ConcurrentDictionary<int, Table>.GetOrAdd method can be used instead of TryGetValue. Or, if the loader delegate must be protected as well, maybe a simple locking dictionary is a better option.

                                  – taffer
                                  1 hour ago













                                  0














                                  A:
                                  pros: none
                                  cons:




                                  • it is not the responsibility of class to track its instances (see SRP)


                                  • non-thread-safe (see ConcurrentDictionary)



                                  B:
                                  pros:




                                  • class is not burdened excess responsibilities that out its scope


                                  cons:




                                  • 'tracking'-code should be encapsulated to separate class that be responsible for creating instances, tracking them, managing time life strategy, etc (factory may fit for that)

                                  • non-thread-safe


                                  As mentioned above If you need to cache some items then use the MemoryCache.






                                  share|improve this answer






























                                    0














                                    A:
                                    pros: none
                                    cons:




                                    • it is not the responsibility of class to track its instances (see SRP)


                                    • non-thread-safe (see ConcurrentDictionary)



                                    B:
                                    pros:




                                    • class is not burdened excess responsibilities that out its scope


                                    cons:




                                    • 'tracking'-code should be encapsulated to separate class that be responsible for creating instances, tracking them, managing time life strategy, etc (factory may fit for that)

                                    • non-thread-safe


                                    As mentioned above If you need to cache some items then use the MemoryCache.






                                    share|improve this answer




























                                      0












                                      0








                                      0







                                      A:
                                      pros: none
                                      cons:




                                      • it is not the responsibility of class to track its instances (see SRP)


                                      • non-thread-safe (see ConcurrentDictionary)



                                      B:
                                      pros:




                                      • class is not burdened excess responsibilities that out its scope


                                      cons:




                                      • 'tracking'-code should be encapsulated to separate class that be responsible for creating instances, tracking them, managing time life strategy, etc (factory may fit for that)

                                      • non-thread-safe


                                      As mentioned above If you need to cache some items then use the MemoryCache.






                                      share|improve this answer















                                      A:
                                      pros: none
                                      cons:




                                      • it is not the responsibility of class to track its instances (see SRP)


                                      • non-thread-safe (see ConcurrentDictionary)



                                      B:
                                      pros:




                                      • class is not burdened excess responsibilities that out its scope


                                      cons:




                                      • 'tracking'-code should be encapsulated to separate class that be responsible for creating instances, tracking them, managing time life strategy, etc (factory may fit for that)

                                      • non-thread-safe


                                      As mentioned above If you need to cache some items then use the MemoryCache.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited 57 mins ago

























                                      answered 1 hour ago









                                      vladimirvladimir

                                      2,2741724




                                      2,2741724






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55898506%2flist-or-dictionary-of-objects-inside-class%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Aikido

                                          Tivadar Csontváry Kosztka

                                          Metroo de Marsejlo