Close

Generics Class Types - O'Reilly way

I found a good Generics  example in C# Cookbook and thought should share. It demonstrate a good use of strong typing and inner classes. I think I'm in compliance with  O'Reilly Policy on Re-Use of Code Examples from Books


Understanding generic class types

            public static void TestGenericClassInstanceCounter()
            {
                  // regular class
                  StandardClass A = new StandardClass(5);
                  Console.WriteLine(A);
                  StandardClass B = new StandardClass(5);
                  Console.WriteLine(B);
                  StandardClass C = new StandardClass(5);
                  Console.WriteLine(C);



                  // generic class
                  
GenericClass<bool> gA = new GenericClass<bool>(5);
      
            Console.WriteLine(gA);
                  GenericClass<int> gB = new GenericClass<int>(5);
                  Console.WriteLine(gB);
                  GenericClass<string> gC = new GenericClass<string>(5);
                  Console.WriteLine(gC);
                  GenericClass<string> gD = new GenericClass<string>(5);
                  Console.WriteLine(gD);

            bool b1 = true;
            bool b2 = false;
            bool bHolder = false;
            // add to the standard class (as object)


            A.AddItem(b1);
            A.AddItem(b2);

            // add to the generic class (as bool)


            gA.AddItem(b1);
            gA.AddItem(b2);

            Console.WriteLine(A);
            Console.WriteLine(gA);


            // have to cast or get error CS0266: 
            // Cannot implicitly convert type 'object' to 'bool'...

            bHolder = (bool)A.GetItem(1);
            // no cast necessary
            bHolder = gA.GetItem(1);


            int i1 = 1;
            int i2 = 2;
            int i3 = 3;
            int iHolder = 0;


            // add to the standard class (as object)
            B.AddItem(i1);
            B.AddItem(i2);
            B.AddItem(i3);


            // add to the generic class (as int)
            gB.AddItem(i1);
            gB.AddItem(i2);
            gB.AddItem(i3);


            Console.WriteLine(B);
            Console.WriteLine(gB);

            // have to cast or get error CS0266: 
            // Cannot implicitly convert type 'object' to 'int'...

            iHolder = (int)B.GetItem(1);

            // no cast necessary
            iHolder = gB.GetItem(1);


            string s1 = "s1";
            string s2 = "s2";
            string s3 = "s3";
            string sHolder = "";


            // add to the standard class (as object)
            C.AddItem(s1);
            C.AddItem(s2);
            C.AddItem(s3);

            // add an int to the string instance, perfectly OK
            C.AddItem(i1);

            // add to the generic class (as string)
            gC.AddItem(s1);
            gC.AddItem(s2);
            gC.AddItem(s3);


            // try to add an int to the string instance, denied by compiler
            // error CS1503: Argument '1': cannot convert from 'int' to 'string'


            //gC.AddItem(i1);


            Console.WriteLine(C);
            Console.WriteLine(gC);


            // have to cast or get error CS0266: 
            // Cannot implicitly convert type 'object' to 'string'...

            sHolder = (string)C.GetItem(1);

            // no cast necessary


            sHolder = gC.GetItem(1);

            // try to get a string into an int, error
            // error CS0029: Cannot implicitly convert type 'string' to 'int'


            //iHolder = gC.GetItem(1);
        }


        public class StandardClass
        {
              // static counter hangs off of the Type for 
              // StandardClass


              static int _count = 0;


            // create an array of typed items


            int _maxItemCount;
            object[] _items;
            int _currentItem = 0;

            // constructor that increments static counter


            public StandardClass(int items)
              {
                _count++;
                _maxItemCount = items;
                _items = new object[_maxItemCount];
              }


            /// <summary>
            /// Add an item to the class whose type 
            /// is unknown as only object can hold any type            
            ///
</summary>
            /// <param name="item">item to add</param>
            /// <returns>the index of the item added</returns>


            public int AddItem(object item)
            {
                
               if (_currentItem < _maxItemCount)
                {
   
                _items[_currentItem] = item;
                    return _currentItem++;
                }
                else
                  throw new Exception("Item queue is full");
            }


            /// <summary>
            /// Get an item from the class
            /// </summary>
            /// <param name="index">the index of the item to get</param>
            /// <returns>an item of type object</returns>


            public object GetItem(int index)
            {
                Debug.Assert(index < _maxItemCount);
                if (index >= _maxItemCount)
                    throw new ArgumentOutOfRangeException("index");
                return _items[index];
            }


            /// <summary>
            /// The count of the items the class holds
            /// </summary>


            public int ItemCount
            {
                get { return _currentItem; }
            }


            /// <summary>
            /// ToString override to provide class detail
            /// </summary>
            /// <returns>formatted string with class details</returns>


            public override string ToString()
              {
                return "There are " + _count.ToString() +
                    " instances of " + this.GetType().ToString() +
                    " which contains " + _currentItem + " items of type " +
                    _items.GetType().ToString() + "...";


            }


        }


        public class GenericClass<T>
        {
             // static counter hangs off of the 
              // instantiated Type for 
              // GenericClass
              static int _count = 0;


            // create an array of typed items
            int _maxItemCount;
            T[] _items;
            int _currentItem = 0;


            // constructor that increments static counter
              public GenericClass(int items)
              {
                _count++;
                _maxItemCount = items;
                _items = new T[_maxItemCount];
            }


            /// <summary>
            /// Add an item to the class whose type 
            /// is determined by the instantiating type
            /// </summary>
            /// <param name="item">item to add</param>
            /// <returns>the zero-based index of the item added</returns>
            public int AddItem(T item)
            {
                
               if (_currentItem < _maxItemCount)
                {
                    _items[_currentItem] = item;
                    return _currentItem++;
                }
                else
                    throw new Exception("Item queue is full");
            }


            /// <summary>
            /// Get an item from the class
            /// </summary>
            /// <param name="index">the zero-based index of the item to get</param>
            /// <returns>an item of the instantiating type</returns>


            public T GetItem(int index)
            {
                Debug.Assert(index < _maxItemCount);
                if (index >= _maxItemCount)
                    throw new ArgumentOutOfRangeException("index");
                return _items[index];
            }


            /// <summary>
            /// The count of the items the class holds
            /// </summary>


            public int ItemCount
            {
                get { return _currentItem; }
            }


            /// <summary>
            /// ToString override to provide class detail
            /// </summary>
            /// <returns>formatted string with class details</returns>
              public override string ToString()
              {
                    return "There are " + _count.ToString() +
                    " instances of " + this.GetType().ToString() + 
                    " which contains " + _currentItem + " items of type " +
                    _items.GetType().ToString() + "...";
              }
        }

Share