Wednesday, September 21, 2011

Generic


C# generics and C++ templates are very similar but they work differently. Generic exist to write code that is reusable across different types.

Let’s imagine we need a stack of integers if we didn’t have generic types, one solution is to hard code a separate version of a class for every required type “IntStack” but when we need stack of string have do the same way “StrStack”. This would cause considerable code duplication.

However this wouldn’t work aAnother solution would be write a stack that is generalizes by using Object as element type.s well hard coded “IntStack” & “StrStack” an “ObjectStack” require boxing & down casting that could not be checked at compile time.

int x = (int)stack.Pop(); // down casting

What we need is both a general implementation of a stack that works for all element type, and a way to easily specialize that stack to a specific element type for increased type safety and reduced boxing and casing.

Generics provide this by allowing parameterize element type.  Stack<T>  has the benefits of both “ObjectStack” and “IntStack”.

Test this example for further understanding.

    class Part
    {
        private string _PartId;
        private string _PartName;
        private string _PartDescription;
        private double _Weight;

        public string PartId { get { return _PartId; } }

        public Part(string PartId, string PartName, string PartDescription, double Weight)
        {
            _PartId = PartId;
            _PartName = PartName;
            _PartDescription = PartDescription;
            _Weight = Weight;

        }

        public override string ToString()
        {
            return string.Format("Part Id: {0}, Part Name:{1}, Part Description:{2}, weight:{3}", _PartId, _PartName, _PartDescription, _Weight);
        }


    }

 

   //the actual indexer, which accepts the generic type
    //note the type must be a class (not a value type)

    class Indexer<T> where T:class
    {
        struct ItemStruct
        {
            public string Key;
            public T value;
            public ItemStruct(string key, T value)
            {
                this.Key = key;
                this.value = value;

            }

        }

        List<ItemStruct> _items = new List<ItemStruct>();

        // T must be a class so that can return null if not found
        public T Find(string key)
        {
            foreach (ItemStruct _ItemStruct in _items)
            {
                if (_ItemStruct.Key == key)
                {
                    return _ItemStruct.value;
                }
            }
            return null;
        }

        public void Add(string key, T value)
        {
            _items.Add(new ItemStruct(key, value));
        }

    }

 
// Programe to Test it

    class Program
    {
        static void Main(string[] args)
        {


            Indexer<Part> indexer = new Indexer<Part>();

            Part p1 = new Part("001", "Mother Board", "Intel Chip set Mother Board", 0.75);
            Part p2 = new Part("002", "Processor", "Intel Core i5", 0.2);

            indexer.Add(p1.PartId, p1);
            indexer.Add(p2.PartId, p2);

            Part p = indexer.Find("002");

            Console.WriteLine(p.ToString());

           
            Console.ReadKey();
        }
    }








No comments:

Post a Comment

Mapping data flows in Azure Data Factory

  Overview: Data flows are one of the features inside the Azure Data Factory which allows data engineers to develop data transformation logi...