Wrox Programmer Forums
Go Back   Wrox Programmer Forums > C# and C > C# 2005 > C# 2005
| Search | Today's Posts | Mark Forums Read
C# 2005 For discussion of Visual C# 2005.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# 2005 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old December 19th, 2009, 04:35 AM
Registered User
 
Join Date: Oct 2008
Location: chennai, tamilnadu, India.
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via AIM to gowrisankar
Default Implementing interface concept in C#

An interface contains only the signatures of methods, delegates or events. The implementation of the methods is done in the class. then we can directly create the function in the class itself, then what is the purpose of interface there ?.
Help Me...
 
Old January 16th, 2010, 02:59 PM
Authorized User
 
Join Date: Nov 2009
Location: Portsmouth,NH
Posts: 22
Thanks: 1
Thanked 3 Times in 3 Posts
Send a message via Yahoo to msherburne84
Default

Check out this link http://bytes.com/topic/c-sharp/answers/246527-what-purpose-interface
this gives a good example of why you should use interfaces
 
Old January 16th, 2010, 10:49 PM
Friend of Wrox
 
Join Date: Jun 2003
Location: , , USA.
Posts: 1,093
Thanks: 1
Thanked 12 Times in 11 Posts
Default

The smashable houses and rocks, and dogs and cats are mammals examples are all valid, but never got me very far. So here is an example based on .Net Framework types that you will use every day of your life as a programmer: enumerating a collection. Consider the following code:

Code:
 
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
 
Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
stack.Push(5);
 
foreach (int item in list)
{
    Console.WriteLine(item);
}
foreach (int item in stack)
{
    Console.WriteLine(item);
}
If you run the above code you will get the following:

1, 2, 3, 4, 5
5, 4, 3, 2, 1

Hmm... We enumerated both the List<T> and the Stack<T> using a 'foreach' statement. Both a List<T> and a Stack<T> wrap an internal array that stores values in the order in which they were added to the List<T> or pushed onto the Stack<T>. So before 'list and 'stack' are passed to the 'foreach' loop, they both wrap an internal array that looks like:

[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 0
[6] = 0
[7] = 0

So...how is the 'foreach' construct smart enough to do a forward enumeration (First-In-First-Out) of the List<T>, and a reverse enumeration (First-In-Last-Out) of the Stack<T>??

The answer: it isn't.

To understand this answer we need to understand a couple of things about the 'foreach' statement in C#. Here's something that MSDN library says about it:

"The foreach statement repeats a group of embedded statements for each element in an array or an object collection that implements the IEnumerable or IEnumerable<T> interface." Then if we look up the IEnumerable or IEnumerable<T> interface we are told that a type that implements them "exposes an enumerator, which supports a simple iteration over a collection."

Yikes. Where are these "embedded statements" and whats an "enumerator"?????

Well, here's where the magic dust gets sprinkled. When we compile the code I listed above, the compiler generates some code for us when it encounters the 'foreach' statement. So I'm going to create a method that basically mirrors the code that the compiler generates for the 'foreach' construct. A foreach loop compiles into the IL equivalent of the iterator pattern, like so:

Code:
static void EnumerateCollection(IEnumerable<int> enumerable)
{
    IEnumerator<int> enumerator = enumerable.GetEnumerator();
    int number = 0;
    try
    {
        while (enumerator.MoveNext())
        {
            number = ((int)enumerator.Current);
            Console.WriteLine(number);
        }
    }
    finally
    {
        IDisposable disposable = (enumerator as IDisposable);
        if (disposable != null)  
        {
            disposable.Dispose();
        }
    }
}
I just wrapped the code in a nifty method called EnumerateCollection() which takes an IEnumerable<T> as a parameter.

What we have so far is the following. The 'foreach' statement doesn't deal with our List<T> as a List<T>, and it doesn't deal with our Stack<T> as a Stack<T>. It deals with our List<T> as an IEnumerable<T> and it deals with our Stack<T> as an IEnumerable<T>, as objects that are capable of exposing an enumerator.

And thats what interfaces do, in part. They let us work with a more abstract representation of our List<T> and Stack<T>. Lists and Stacks can do all sorts if things: add items, remove items, move items, count items, search for or iterate over items they contain. Lists can even order items. So far as using a List<T> or a Stack<T> with a 'foreach' statement is concerned, we don't care about all the abilities that Lists and Stacks have. We are only concerned with an abstraction, a subset of the abilities that Lists and Stacks posess: their ability to expose an enumerator. Up-casting ("abstracting") our List<T> and Stack<T> to IEnumerable<T> (which both types implement), allows us to expose only this subset of abilitities to the construct consuming the List<T> and Stack<T>.

The IEnumerable<T> interface defines a single method: GetEnumerator(). Calling GetEnumerator() returns an instance of an IEnumerator<T>.

What is an IEnumerator<T>??? IEnumerator<T> is an interface which defines MoveNext and Reset methods, and a Current property. The MoveNext method and Current property are demonstrated in the "compiler generated code" I listed above. Enumerators are objects that implement the IEnumerator<T> interface. The details of Enumerator implementations are kinda' beyond the scope of this post, but look at the C# representation of List<T> and Stack<T> in Reflector. You will see that both implement their Enumerator objects as nested structs.

So how can the 'foreach' statement perform both a forward enumeration (First-In-First-Out) in the case of the List<T> and a reverse enumeration (Last-In-First-Out) in the case of the Stack<T>. It can because List.Enumerator is implemented to perform a forward enumeration and Stack.Enumerator is implemented to perform a reverse enumeration. That is to say, List<T>.Enumerator.MoveNext() moves forwards over the elements in the List's internal array, starting with the first element; Stack<T>.Enumerator.MoveNext() moves backwards over the elements in the Stack's internal array, starting with the last element.

The 'foreach' statement simply calls the GetEnumerator() method of the List<T> and the Stack<T> treated as IEnumerables. Its the returned Enumerators themselves that implement the forward and reverse iteration logic.

The beauty of interfaces is that we can pass any type we want to a 'foreach' construct so long as the type implements IEnumerable<T>. The 'pattern' of the 'foreach' iteration is dictated by the custom iteration semantics implemented by the enumerator the type exposes. In other words, the 'foreach' contruct doesn't know how to enumerate a type; it only knows how to get the IEnumerator<T> a type exposes, and how to consume that IEnumerator<T> by calling its MoveNext() method and examining its Current property. The enumertor's MoveNext() method encapsulates the logic which dictates the pattern of the enumeration.

By implementing IEnumerable<T>, the type is essentially establishing an immutable contract with the client code that declares:

"I have a GetEnumerator() method you can call, which returns an enumerator you can consume by calling its MoveNext() method and examining its Current property. Don't worry about the implementation details of these members. I got that all worked out!"

And the 'foreach' construct doesn't care about the implementation details of the enumerator; it is completely "decoupled" from them. It will work just fine with any type that can return an enumerator (i.e., that implements IEnumerable<T>). So if we know a type implements IEnumerable<T>, we know that it implements a GetEnumerator() method which returns an IEnumerator<T>, and we know that we can use it with constructs that expect an IEnumerable<T>, like the 'foreach' statement. The C# 'yield return' construct is another that returns a compiler generated state machine that implements IEnumerable<T> and IEnumerator<T>. All of the LINQ to Objects query methods are implemented as extension methods that return IEnumerables.

A client consuming these constructs doesn't need to know anything about the implementation details of the enumerator itself; whether it performs a forward iteration, a reverse iteration, an iteration that evaluates each item against a predicate, an iteration that buffers items and orders them, an iteration that manages state and stops execution at yeild points. All these implementation details are encapsulated in the enumerators themselves. All our client code that consumes the enumerator needs to know is: "Can I GET an enumerator for this type?". The presence of the IEnumerable<T> interface on a type tells our client code that it can.

So here is a revised version of the code from the top of this post that used 'foreach' loops. It performs identically to using 'foreach' loops:

Code:
using System;
using System.Collections.Generic;
 
 
namespace Why_Use_Interfaces
{
    classProgram
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int> { 1, 2, 3, 4, 5 };
 
            Stack<int> stack = new Stack<int>();
            stack.Push(1);
            stack.Push(2);
            stack.Push(3);
            stack.Push(4);
            stack.Push(5);
 
            EnumerateCollection(list);
            EnumerateCollection(stack);
        }
 
        static void EnumerateCollection(IEnumerable<int> enumerable)
        {
            IEnumerator<int> enumerator = enumerable.GetEnumerator();
            int number = 0;
 
            try
            {
                while (enumerator.MoveNext())
                {
                    number = ((int)enumerator.Current);
                    Console.WriteLine(number);
                }
            }
            finally
            {
                IDisposable disposable = (enumerator asIDisposable);
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
    }
}
There, instant polymorphic code reuse - one method that can enumerate both Lists and Stacks (and Arrays and Queues and Dictionaries and Strings and probably hundreds of other types) all abstracted as IEnumerables. Without the kind of polymorphic code reuse afforded by interfaces, the authors of the .NET Framework would have had to write about three to four HUNDRED versions of the 'foreach' construct, one for each type that wants to expose the ability to be enumerated. Getting the picture?:)

Notice also that our method can treat the returned Enumerators as IDisposables, to release any unmanged resources when we are done with them.

IEnumerable<T> and IEnumerator<T> (and their non-generic counterparts) are the most prevalent .NET interfaces in the framework. You can't pick a better pair to study to get the hang of how interfaces work, and why you would want to use them. They are everywhere.

HTH,

Bob

Last edited by Bob Bedell; January 18th, 2010 at 12:38 AM..
The Following User Says Thank You to Bob Bedell For This Useful Post:
Imar (January 17th, 2010)
 
Old January 17th, 2010, 12:32 PM
Friend of Wrox
 
Join Date: Jun 2003
Location: , , USA.
Posts: 1,093
Thanks: 1
Thanked 12 Times in 11 Posts
Default

Here's a generic version of the method and a few more types to enumerate:

Code:
using System;
using System.Collections.Generic;
 
namespace WhyUseInterfaces
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int> { 1, 2, 3, 4, 5 };
 
            Stack<int> stack = new Stack<int>();
            stack.Push(1);
            stack.Push(2);
            stack.Push(3);
            stack.Push(4);
            stack.Push(5);
 
            double[] array = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0 };
 
            Queue<string> queue = new Queue<string>();
            queue.Enqueue("a");
            queue.Enqueue("b");
            queue.Enqueue("c");
            queue.Enqueue("d");
            queue.Enqueue("e");
 
            Dictionary<int, string> dictionary = newDictionary<int, string>();
            dictionary.Add(1, "a");
            dictionary.Add(2, "b");
            dictionary.Add(3, "c");
            dictionary.Add(4, "d");
            dictionary.Add(5, "e");
 
            String aString = "abcde";


            // Enumerate Types
            ForEach(list);
            ForEach(stack);
            ForEach(array);
            ForEach(queue);
            ForEach(dictionary);
            ForEach(aString);
        }
 
        public static void ForEach<T>(IEnumerable<T> enumerable)
        {
            IEnumerator<T> enumerator = enumerable.GetEnumerator();
            T current = default(T);
 
            try
            {
                while (enumerator.MoveNext())
                {
                    current = ((T)enumerator.Current);
                    Console.WriteLine(current);
                }
            }
            finally
            {
                IDisposable disposable = (enumerator as IDisposable);
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
    }
}
The Dictionary output is especially interesting. The Current property of Dictionary.Enumerator is implemented to return a KeyValuePair<TKey, TValue>. The ToString() method of KeyValuePair<TKey, TValue> is overriden to return:

[1, a]
[2, b]
[3, c]
[4, d]
[5, e]

So far we've enumerated 6 different types, all with their own, unique iteration semantics, with a single method, simply by treating them as instances of the IEnumerable<T> interface. Multiply that by the hundreds of types in the Framework that implement IEnumerable<T>, and the utility of working with types as instances of the interfaces they implement is driven home pretty clearly.

Last edited by Bob Bedell; January 17th, 2010 at 02:01 PM..
The Following User Says Thank You to Bob Bedell For This Useful Post:
msherburne84 (January 17th, 2010)
 
Old January 18th, 2010, 07:50 PM
Friend of Wrox
 
Join Date: Jun 2003
Location: , , USA.
Posts: 1,093
Thanks: 1
Thanked 12 Times in 11 Posts
Default

Having said all that, I should probably mention that the 'foreach' statement doesn't require the types it operates on to be statically typed (i.e., implement interfaces). The 'foreach' statement also supports duck typing.

When 'foreach' uses duck typing to decide if a type is enumerable or not, it doesn't require that the type implement the IEnumerable or IEnumerable<T> interface. Instead, it requires the type to satisfy a minimum set of member definition conventions. That set includes:

- A public, parameterless method named 'GetEnumerator'.
- GetEnumerator has to return a type with:
- a public, parameterless method named 'MoveNext' that returns a Boolean.
- a public, read-only property named 'Current' with a get accessor that returns an Object.

The type that 'GetEnumerator' returns does not have to be statically typed either (i.e., implement IEnumerator or IEnumerator<T>).

Sound familiar. Hence the name "duck-typing": If it looks like an IEnumerable, and walks like an IEnumerable, and quakes like an IEnumerable......

Anyway, here's a custom duck-typed list the works just fine with 'foreach'. (I'm cheating and wrapping a List instead of an array to get 'automatic' capacity re-sizing. Keeps it simple). No interfaces implemented.

Code:
using System;
using System.Collections.Generic;
 
namespace Duck_Typing_ForEach
{
   class Program
   {
       static void Main(string[] args)
       {
           DuckTypedList<int> list = new DuckTypedList<int>();
           list.Add(1);
           list.Add(2);
           list.Add(3);
           list.Add(4); 
           list.Add(5);
 
           foreach (int item in list)
           {
               Console.WriteLine(item);
           }
       }
   }
 
   class DuckTypedList<T> 
   {
           private List<T> _items = new List<T>();
 
           public void Add(T item)
           {
               this._items.Add(item);
           }
 
           public Enumerator GetEnumerator()
           {
               return new Enumerator((DuckTypedList<T>)this);
           }
 
           public struct Enumerator
           {
               private DuckTypedList<T> _list;
               private int _index;
 
               public Enumerator(DuckTypedList<T> list)
               {
                   _list = list;
                   _index = -1;
               }
 
               public object Current
               {
                   get { return _list._items[_index]; }
               }
 
               public bool MoveNext()
               {
                   _index++;
                   if (_index >= _list._items.Count)
                       return false;
                   else
                       return true;
               }
           }
       }
}

Last edited by Bob Bedell; January 18th, 2010 at 07:54 PM..




Similar Threads
Thread Thread Starter Forum Replies Last Post
implementing a region in interface mohammadalsayeh .NET Framework 2.0 1 August 27th, 2007 08:28 PM
XMail Concept (Help) gmbalaa General .NET 1 August 26th, 2007 01:57 PM
Implementing The Comparable Interface andyboer Java Basics 4 May 18th, 2007 05:03 AM
Problem With Implementing an Interface brettk_1 General .NET 1 February 28th, 2007 11:47 AM
Design Concept shazza Biztalk 1 August 23rd, 2006 09:54 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.