Collection Framework and Reflection in C#

Question 1: Collection Framework.

Answer

A collection is a set of similarly typed objects that are grouped together.

A collections is a set of similarly type of elements that are grouped together System.Collection namespace contains interfaces and classes that define various collections of objects, such as lists, queue, hash tables and dictionaries, and so on.

Memory management is done automatically for all the collections. This becomes easy for a .NET developer to handle objects. Types of collections available in .Net framework are as follows.

Collections can contain mainly two types:

  1. Arrays
  2. Advance Collections
    • Non Generic
    • Generic

Collection

1. Arrays

Array class is defined in System namespace. Arrays can store any type of data but only one type at a time. The size of the array has to be specified at compiler time and we cannot insert, delete an element from an array randomly. If done programmatically, it is at the cost of performance.

2. Advance Collections

There are various operations that are required to process data. There include searching, sorting, insertion, comparing, and so on. To perform these operations efficiently, the data needs to be organized in a specific way. This gives rise to advance collections. Advanced collections are found in System. Collections namespace. They are subcategorized as non-generic and generic collections.

Non-generic collections are defined in this namespace prior to .NET framework 2.0. They are Array List, Stack, Queue, Hash Table, and so on. Every element in non-generic collection is stored as System. Object type.

The generic collections are defined in the System.Collections.Generic namespace in Framework 2.0. They are generic list, generic stack, generic queue, and so on. They are template-based versions of non-generic counterparts.

Every class in the collections has a unique feature. Some classes have sorting capability; some are based on a specific axiom. For example, a stack is based on the principle of List In First Out (LIFO) whereas a queue is based on First in First Out (FIFO). Collections like a Hash Table and Dictionary are stored as key value pairs. Elements in an Array List are similar to an Array but it can grow dynamically whenever a new element is added.

Array Class

namespace ArrayClass

{

    class Program

    {

        static void Main(string[] args)

        {

            string[] strarry = new string[] { "First",

"Second", "Third", "Fourth", "Fifth" };

            string[] strdest = new string[5];

            int[] inarry = new int[] { 3, 6, 44, 123, 88 };

            //Sort Array

            Array.Sort(strarry);

            foreach (string s in strarry)

            {

                Console.WriteLine(s);

            }

            Console.WriteLine("---------------");

            //Reverse Array

            Array.Reverse(strarry);

            foreach (string s in strarry)

            {

                Console.WriteLine(s);

            }

            Console.WriteLine("---------------");

            //Copy Array in Another Array

            Array.Copy(strarry, strdest, 0);

            foreach (string s in strarry)

            {

                Console.WriteLine(s);

            }

            Console.WriteLine("---------------");

            Console.ReadLine();

        }

    }

}

Array List Class
 

namespace ArrayListClass

{

    class Program

    {

        static void Main(string[] args)

        {

            int[] arr = new int[3] { 1, 2, 3 };

            ArrayList country = new ArrayList();

            country.Add("India");

            country.Add("Japan");

            country.Add("Spain");

            country.Add("UK");

            Console.WriteLine("Count: {0}", country.Count);

            Console.WriteLine("---Display ArrayList----");

            foreach (string str in country)

            {

                Console.WriteLine(str);

            }

            Console.WriteLine("--Remove From ArrayList-");

            country.Remove("Japan");

            foreach (string str in country)

            {

                Console.WriteLine(str);

            }

            Console.WriteLine(country.Count);

            Console.WriteLine("----Add In ArrayList --");

            country.Add("US");

            foreach (string str in country)

            {

                Console.WriteLine(str);

            }

            Console.WriteLine("------Count--------------");

            Console.WriteLine(country.Count);

            Console.ReadLine();

        }

    }

}


Hash Table
 

namespace CollectionApp

{

    class HastTableClass

    {

        public static void Main()

        {

            Hashtable ht = new Hashtable();

            ht.Add(001, "monday");

            ht.Add(002, "tuesday");

            ICollection obj = ht.Keys;

            foreach (int i in obj)

            {

                Console.WriteLine(i + ":" + ht[i]);

            }

            IDictionaryEnumerator e = ht.GetEnumerator();

            while (e.MoveNext())

            {

                Console.WriteLine(e.Key + "\t" + e.Value);

            }

            Console.ReadLine();

        }

    }

}

Stack Demo
 

namespace CollectionApp

{

    class StackCls

    {

        static void Main()

        {

            // Stack ss = new Stack();

            //ss.Push(11);

            //ss.Push("fsd");

            Stack<string> ss = new Stack<string>();

            //Stack<int> myStack = new Stack<int>();

            //myStack.Push(1);

            ss.Push("dfsf");

            ss.Push("dfs");

            ss.Push("df");

            ss.Push("d");

            //myStack.Push(2);

            //myStack.Push(3);

            //myStack.Push(4);

            //myStack.Push(5);

            foreach (string i in ss)

            {

                Console.WriteLine(i);

            }

            Console.WriteLine("-------POP-----------");

            ss.Pop();

            foreach (object i in ss)

            {

                Console.WriteLine(i);

            }

            Console.ReadLine();

        }

    }

}

Queue Demo
 

namespace CollectionApp

{

    class QueueCls

    {

        public static void Main()

        {

            //Queue<int> qq = new Queue<int>();

            Queue q = new Queue();

            q.Enqueue("One");

            q.Enqueue(2);

            q.Enqueue("Three");

            q.Enqueue(4);

            Console.WriteLine("------Display--------");

            foreach (object s in q)

            {

                Console.WriteLine(s);

            }

            Console.WriteLine("count=" + q.Count);

            Console.WriteLine("-----Remove From Queue---");

            Console.WriteLine("Removed=" + q.Dequeue());

            //return and remove object

            foreach (object s in q)

            {

                Console.WriteLine(s);

            }

            Console.WriteLine("count=" + q.Count);

            Console.WriteLine("----Peek from Queue-----");

            Console.WriteLine(q.Peek());//peek returns object without removing it

            Console.ReadLine();

        }

    }

}

Generic Demo
 

namespace ConsoleApplication1

{

    class myGenClass<T>

    {

        public T a;

    }

    class myGenClass2<T1, T2>

    {

        public T1 a;

        public T2 b;

    }

    class clsUseGeneric

    {

        static void Main()

        {

            myGenClass<int> i = new myGenClass<int>();

            i.a = 9;

            Console.WriteLine(i.a);

            int b = i.a + i.a;

            Console.WriteLine("Addition :-" + b);

            myGenClass<string> str = new

            myGenClass<string>();

            str.a = "Peter";

            Console.WriteLine(str.a);

            myGenClass2<int, string> mix = new

            myGenClass2<int, string>();

            mix.a = 99;

            mix.b = "Roy";

            Console.WriteLine(mix.b + " " + mix.a);

            Console.ReadLine();

        }

    }

}


Question 2: Reflection

Answer

Reflection is the ability to examine the metadata in the assembly manifest at runtime.

Reflection is useful in the following situations:

  1. Need to access attributes in your program's metadeta.
  2. To examine and instantiate types in an assembly.
  3. To build new types at runtime using classes in System.Reflection.Emit.
  4. To perform late binding, accessing methods on types created at run time.

.NET assembly consists of four parts

  1. Assembly manifest
  2. Type Metadeta
  3. MSIL code
  4. Resource

The metadata is information describing the program that is stored either in a Common Language Runtime Portable Executable (PE) file, or in memory during execution of code, the runtime loads the metadata into memory and references it to discover information about the code's classes, members, inheritance, and so on.

Similarly, reflection is a technique provided for developers to examine the metadata at runtime. It is used to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its field and properties.

System.Type class

Provides access to metadata for any .NET type.

Refelection

System.Type is the class to access metadata. The Type class defines a number of members to get information about a type; its constructor, methods, fields, properties and events.

System. Reflection Namespace

Contains classes and interfaces that provide a managed view of loaded types, methods, and fields.

These types provide the ability to dynamically create and invoke types.

Type

Description

Module Perform reflection on module.
Assembly Load assembly at runtime and get its type
Member Info Obtains information about the attributes of a member and provides access to member metadata.

1. Demo Program for Reflection

namespace Reflection_Demo

{

    class Program

    {

        static void Main(string[] args)

        {

            Type[] types;

            Assembly asm = Assembly.LoadFrom(@"d:\ClassLibrary1.dll");

            types = asm.GetTypes();

            foreach (Type t in types)

            {

                Console.WriteLine(t.Name);

                MemberInfo[] members = t.GetMembers();

                MemberTypes memtype;

                foreach (MemberInfo m in members)

                {

                    memtype = m.MemberType;

 

                    switch (memtype)

                    {

                        case MemberTypes.Property: Console.WriteLine("Properties:");

                            Console.WriteLine(m.Name);

                            break;

                        case MemberTypes.Method: Console.WriteLine("Methods:");

                            Console.WriteLine(m.Name);

                            break;

                        case MemberTypes.Constructor: Console.WriteLine("Constructors:");

                            Console.WriteLine(m.Name);

                            break;

                    }

                }

                Console.ReadLine();

            }

        }

    }

}

  
2. RunTime_Binding Demo in reflection.
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

 

namespace RunTime_Binding

{

    class Program

    {

        static void Main(string[] args)

        {

            Assembly asm = Assembly.LoadFrom(@"d:\MathLib.dll");

            MemberInfo method;

            object result = new object();

            object[] arg = new object[] { 30, 20 };

 

            Type[] types = asm.GetTypes();

 

            foreach (Type t in types)

            {

                method = t.GetMethod("sub");

 

                if (method != null)

                {

                    string typeName = t.FullName;

                    object obj = asm.CreateInstance(typeName);

                    result = t.InvokeMember(method.Name, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, obj, arg);

                    break;

                }

            }

            Console.WriteLine("Result is : {0}", result);

            Console.ReadLine();

        }

    }

}