Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 185
  • Last Modified:

Am I using Generics the right way?

Hello,

I have started to play with Generics in C# 2.0.  I know what they are about but still a little unsure on how to use Generics appropriatly.  Below is my first attempt at using Generics.  If I were to use code as show below, am I realizing the benefits of Generics (i.e. type-safety, performance improvement, no need to (un)box, etc)?  

Thanks

public class EmployeeCollection : IEnumerable<Employee>
{
   List<Employee> m_empCollection = new List<Employee>();
       
   public EmployeeCollection()
   {}

    public void Add(Employee newItem)
    {
        m_empCollection.Add(newItem);
     }

    public void Remove(Employee oldItem)
    {
         m_empCollection.Remove(oldItem);
     }

     public Employee this[int index]
     {
         get { return m_empCollection[index]; }
      }

     public int Count
     {
         get { return m_empCollection.Count; }
     }

     #region IEnumerable<Employee> Members
     public IEnumerator<Employee> GetEnumerator()
     {
        return m_empCollection.GetEnumerator();
     }

    #endregion

    #region IEnumerable Members

     IEnumerator IEnumerable.GetEnumerator()
     {
         return m_empCollection.GetEnumerator();
     }

    #endregion
}
0
brdrok
Asked:
brdrok
  • 2
  • 2
2 Solutions
 
AlexFMCommented:
Assuming that Employee is class (reference type):

Type-safety - yes. Using List<Employee> instead of ArrayList ensures type safety.
Performance improvement - minimal. Code working with List<Employee> doesn't need to make runtime casting (like ArrayList requires), this gives some performance improvement.
Unboxing - doesn't apply here, because Employee is reference type.

Assuming that Employee is structure (value type):

Type-safety - yes.
Performance improvement - significant. Code working with List<Employee> doesn't need to make runtime casting (like ArrayList requires) and doesn't need to make boxing. ArrayList requires boxing for value type, because it works with Objects.
Unboxing - using List<Employee> prevents unboxing.

Performance improvement and no unboxing - this also applies for primitive value types, like int, double etc.

Notice that  List<Employee> class itself implements IEnumerable<Employee>, it can do all that your EmployeeCollection class does.
0
 
devsolnsCommented:
Yeah I was going to point out, but Alexs already did that your functionality is already in List<T>.
0
 
brdrokAuthor Commented:
Thanks for the very awesome reply.  In this case, Employee would be a reference type.  Eventually something like this will be used in a web application and I figure every little performance gain wouldn't hurt.  

When you wrote:
Notice that  List<Employee> class itself implements IEnumerable<Employee>, it can do all that your EmployeeCollection class does

I am not sure what you mean by that.  Back in the 1.1 days,  I would have something like:
public class EmployeeCol : CollectionBase

the reason being is that the CollectionBase already implements all the goody interfaces (IList, ICollection, IEnumerable)

Are you perhaps suggesting to have the EmployeeCollection class inherit from the Generic.List<....> class? i.e.

public class EmployeeCollection : System.Collections.Generic.List<Employee>
0
 
brdrokAuthor Commented:
Perhaps it's a judgement call, but more often than not, I found myself using the indexer quite a bit.  In 1.1., I often times would have something like this:

public Employee this[int index]
{
  get { return ((Employee)(List[index])); }
}

having to type-cast (hopefully I using the right terminology here).  With Generics, I am not dealing with "object" types anymore.  Am I right or off-base?
0
 
AlexFMCommented:
I mean, unless you add some other functions to EmployeeCollection class, it doesn't have any more functionality than its m_empCollection member. Notice that every public function or property, including indexer, is redirected to exactly same member of m_empCollection.
Suppose I am client of this class. What features does it have which can convince me to use it? I can create List<Employee> myself and have the same functionality. Wrapper only adds operations reducing performance.
However, if you have some other code in this class, this makes sence.

About casting in indexer - you are right. All operations with generic collections are done without casting, this is main generic collections advantage.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now