Author Topic: Creating a collection class  (Read 7411 times)

0 Members and 1 Guest are viewing this topic.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Creating a collection class
« on: July 06, 2013, 03:09:57 AM »
I have a class that will be used to manage multiple objects of a specific type, I have read that IEnumerable and IList are the appropriate interfaces to use. I have never done this and the samples I have seen only seem to gloss over the process.

I am looking for the ability to add/remove/sort/count etc. the objects from the parent.

Anyone want to volunteer to point me in the right direction?
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

BlackBox

  • King Gator
  • Posts: 3770
Re: Creating a collection class
« Reply #1 on: July 06, 2013, 04:03:53 AM »
Simply derive (inherit) your custom Type(s) from the desired Type/Interface, to access shared Properties, Methods, and Events:
Code - C#: [Select]
  1. class Foo : IEnumerable
  2. {
  3.      // constructor here
  4. }
  5.  
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Creating a collection class
« Reply #2 on: July 06, 2013, 04:31:31 AM »
IList implements ICollection and IEnumerable
Code - C#: [Select]
  1. namespace System.Collections.Generic
  2. {
  3.     using System;
  4.     using System.Collections;
  5.     using System.Reflection;
  6.     using System.Runtime.CompilerServices;
  7.  
  8.     public interface ICollection<T> : IEnumerable<T>, IEnumerable
  9.     {
  10.        
  11.         void Add(T item);
  12.        
  13.         void Clear();
  14.        
  15.         bool Contains(T item);
  16.        
  17.         void CopyTo(T[] array, int arrayIndex);
  18.        
  19.         bool Remove(T item);
  20.        
  21.         int Count {  get; }
  22.        
  23.         bool IsReadOnly {  get; }
  24.     }
  25.     public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
  26.     {
  27.      
  28.         int IndexOf(T item);
  29.      
  30.         void Insert(int index, T item);
  31.      
  32.         void RemoveAt(int index);
  33.        
  34.         T this[int index] {  get; set; }
  35.     }
  36. }
  37.  

If you are fine with it behaving like a list then you can simply
Code - C#: [Select]
  1.         class foo
  2.         {
  3.         }
  4.         class fooList : List<foo>
  5.         {
  6.         }
  7.  

If you want different behavior  you can encapsulate a list inside your class and implement the behavior yourself
Code - C#: [Select]
  1. class fooCollection : ICollection<foo>
  2.         {
  3.             private List<foo> foos = new List<foo>();
  4.             public void Add(foo item)
  5.             {
  6.                 foos.Add(item);
  7.             }
  8.             public void Clear()
  9.             {
  10.                 throw new NotImplementedException();
  11.             }
  12.             public bool Contains(foo item)
  13.             {
  14.                 throw new NotImplementedException();
  15.             }
  16.             public void CopyTo(foo[] array, int arrayIndex)
  17.             {
  18.                 throw new NotImplementedException();
  19.             }
  20.             public int Count
  21.             {
  22.                 get { throw new NotImplementedException(); }
  23.             }
  24.             public bool IsReadOnly
  25.             {
  26.                 get { throw new NotImplementedException(); }
  27.             }
  28.             public bool Remove(foo item)
  29.             {
  30.                 throw new NotImplementedException();
  31.             }
  32.             public IEnumerator<foo> GetEnumerator()
  33.             {
  34.                 throw new NotImplementedException();
  35.             }
  36.             System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  37.             {
  38.                 throw new NotImplementedException();
  39.             }
  40.         }
  41.  
It just depends on what you will be doing with them

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Creating a collection class
« Reply #3 on: July 08, 2013, 09:37:47 AM »
Jeff, that looks like what I want to do, although I may have complicated the issue a bit. I don't really need to manipulate the collection, I merely need to store it for later use, and do so in a way that works like a default List<T> using my class of object.

To that end, I could simply declare a List<T> and expose the public properties and methods to the user ... would that be enough? Keep in mind I would implement all of the properties and methods I needed.

Code - C#: [Select]
  1. class MyObjectCollection {
  2.     List<MyObject> _contents;
  3.  
  4.    public void Add(MyObject item)
  5.    {
  6.         _contents.Add(MyObject);
  7.    }
  8.    public int Count()
  9.    {
  10.         get
  11.         {
  12.               return _contents.Count;
  13.         }
  14.    }
  15.    public void Clear()
  16.    {
  17.        _contents.Clear();
  18.    }
  19. }
  20.  

Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

n.yuan

  • Bull Frog
  • Posts: 348
Re: Creating a collection class
« Reply #4 on: July 08, 2013, 12:41:29 PM »
Why you do a class that CONTAINS a List<T> instead of do a class that IS List<T> (that is, derive a class based on List<T>) for your simple Collection need?

If you:

class MyObjectCollection:List<MyObject>
{

}

Then the class has already the regular Add()/Remove()/Clear() methods available. You simply add your own properties/methods that List<T> do not have.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Creating a collection class
« Reply #5 on: July 08, 2013, 01:42:08 PM »
That seems to be simple enough ... it seems as though I have complicated it.

So, if I create my manager class and inherit List<T> then I don't even need to implement the properties for the collection?

This is how I hope to develop the objects.

Top level class "Manager" does all of the work. Because I use the same data to populate multiple controls and control types, I manage the collection by first creating the manager by passing a valid database connection and a control to populate.

Code - C#: [Select]
  1. objManager oMgr = New objManager(_datalayer, thisControl);
  2.  

The manager has the following functions:
Code - C#: [Select]
  1. bool LoadAll(bool active = true, string filter = "")
  2. bool LoadGroups(bool active = true, string filter = "")
  3. bool LoadOrphans(bool active = true, string filter = "")
  4. bool LoadChildren(string parent, bool active= true, string filter = "")
  5.  

The functions load the data from the database and populates the correct control with all of the data. The objects are manipulated in their own class so I can derive the necessary information from them. Also, because I need to be able to create additional objects on the fly, I need to have a collection that I can manipulate.

When I select an item in the control, the value represents the ID of the database record. This loads the object data from the database and builds the object. The object is then added to the object manager.

Code - C#: [Select]
  1. objManagedItem oManagedItem = New objManagedItem();
  2. oMgr.Items.Add(oManagedItem);
  3.  

Can I hook an event to the items in the collection to fire an internal function when it changes?
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

BlackBox

  • King Gator
  • Posts: 3770
Re: Creating a collection class
« Reply #6 on: July 08, 2013, 04:38:40 PM »
Simply derive (inherit) your custom Type(s) from the desired Type/Interface, to access shared Properties, Methods, and Events:

Why you do a class that CONTAINS a List<T> instead of do a class that IS List<T> (that is, derive a class based on List<T>) for your simple Collection need?

...

Then the class has already the regular Add()/Remove()/Clear() methods available. You simply add your own properties/methods that List<T> do not have.

That seems to be simple enough ... it seems as though I have complicated it.

So, if I create my manager class and inherit List<T> then I don't even need to implement the properties for the collection?



Correct... This is due to what's known as 'Implementation Inheritance':

Quote from: MSDN, Inheritance from a Base Class in Microsoft .NET

Inheritance Terminology

There are three types of inheritance that .NET supports: implementation, interface, and visual. Implementation inheritance refers to the ability to use a base class's properties and methods with no additional coding. Interface inheritance refers to the ability to use just the names of the properties and methods, but the child class must provide the implementation. Visual inheritance refers to the ability for a child form (class) to use the base forms (class) visual representation as well as the implemented code.

A class in .NET may inherit from a class that has already inherited from another class. In addition you may use an interface or even multiple interfaces within a class.
"How we think determines what we do, and what we do determines what we get."

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Creating a collection class
« Reply #7 on: July 08, 2013, 05:51:15 PM »
Then I don't need to do anything? Can it be that easy?
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

BlackBox

  • King Gator
  • Posts: 3770
Re: Creating a collection class
« Reply #8 on: July 08, 2013, 05:56:06 PM »
Then I don't need to do anything? Can it be that easy?

If you simply need a custom Class that inherits the properties, methods, and events of another type or interface... Yes.

What shortcomings (if any) have you experienced when implementing?

"How we think determines what we do, and what we do determines what we get."

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Creating a collection class
« Reply #9 on: July 08, 2013, 11:14:35 PM »
Well, I haven't fully implemented it yet. Right now the class works like this:

Create a new manager object passing a database connection and control in the constructor.

The user then passes a few arguments (or not) to one of the 4 methods described above and the manager retrieves the data from the database, formats it in a way that is compatable with the passed control and populates the control with the data (the control may be a ComboBox, ListBox, ListView or TreeView).

This is what the manager does on initialization. On postback, (this is a web application) the manager is instantiated with the database connection and control the same as before, but depending upon what caused the postback, the manager will either add a new item to the collection of things used to populate the control, delete an item from the collection or modify an existing item in the collection. The data is held in a transient state until the SaveAll method of the manager is called. This will then commit the objects in the collection to the database. Whether the items are saved is based upon the user's actions and the postback values.

Because this is a web application, all data is transient and exists only for the duration of the execution of the server-side code, and long enough to populate the control with the data that is displayed to the user.

I probably don't need to be as complex as I want to make these objects, but I will certainly be using this class in another application in the future, thus the ability to edit objects in the collection is of importance. Also, I will very likely be adding additional properties and methods to the objects in the collection, so creating a derived class, inherited from List<T> is also probably the way I want to go with this, not to mention that I will likely be using this class in other data object managers.

So, lets just start at the beginning.

I have an object that is created from data in the database. We will call this object "Shift" (remember this is a medical staffing and patient manager).
For each building, there may be many shifts that need to be created and displayed to the user in a ListBox, ComboBox, or perhaps a DataGrid. To keep all of the shifts in one location, I will create a "ShiftCollection" that holds all of the "Shift" objects. This collection is a simple List<Shift> and thus I am able to add/edit/delete any of the "Shift" objects in "ShiftCollection".

In my "ShiftManager" class, I will have a private variable of "ShiftCollection" (lets call it _shiftCollection). The private variable _shiftCollection will be exposed through an Items property. Now, I can instantiate my ShiftManager class with the control and database connection, then fill the _shiftCollection object with one of the four methods described in my earlier post. This will load all of the Shift objects from the database, placing each into the _shiftCollection object.

Once I have ShiftManager instantiated and filled, I can then edit the ShiftCollection through the Items property of the ShiftManager, adding, deleting or editing the contents as needed.

The only part that I am unclear with now, is how can I call the private method in ShiftManager to clear all items from the control and populate it with the new collection once the collection or an item in the collection has changed? Is there an event that is fired when the collection is modified or do I have to create my own events (for example OnShiftEdit event, then bubble up to the collection which fires an OnShiftCollectionModified event that the manager class can catch and call the correct function to update the control)?

Oh, and one final thing, if I make Items the default property, can I then access the items in the List<Shift> by like this:
Code - C#: [Select]
  1. shift Items[int index]
  2. {
  3.     get
  4.     {
  5.          return _shiftCollection[index];
  6.     }
  7.     set
  8.     {
  9.         _shiftCollection[index] = value;
  10.     }
  11. }
  12.  
  13. shift thisShift = ShiftManager.Item[n];
  14.  
« Last Edit: July 08, 2013, 11:27:57 PM by Keith™ »
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

BlackBox

  • King Gator
  • Posts: 3770
Re: Creating a collection class
« Reply #10 on: July 09, 2013, 03:02:06 AM »
Quote
The only part that I am unclear with now, is how can I call the private method in ShiftManager to clear all items from the control and populate it with the new collection once the collection or an item in the collection has changed?

Couple of things... Couldn't you simply implement an override for the Clear() Method which accepts your collection?

Also, is there a reason you chose to inherit from List<Shift>, rather than implement Shift[]? Particularly given your Items[int index] property, which would be inherited from Shift[].

I'd have to explore the event inheritance (if any). *not sure*
"How we think determines what we do, and what we do determines what we get."

fixo

  • Guest
Re: Creating a collection class
« Reply #11 on: July 09, 2013, 04:13:16 AM »
Just for your interest, here is the way to do it
dynamically, see for more:
http://codearticles.ru/articles/944

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Creating a collection class
« Reply #12 on: July 09, 2013, 08:59:12 PM »
Another nice thing about using IList is the ability to run LINQ against your object.
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

BlackBox

  • King Gator
  • Posts: 3770
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Creating a collection class
« Reply #14 on: July 10, 2013, 09:33:20 AM »
I am just starting to learn MVC 4, and maybe some else knows but I thought you could easily bind data to your controls, but I do not know enough.