locked
IEnumerable<> RRS feed

  • Question

  • I am struggle to understand alot of the code below from a book

    it seems to have put bits in without full explanations....

     

    I thought  IEnumberable was an interface exposing methods.....

     

    But below it is uesd like a type i think ....?

     

     

    public Vectors(IEnumerable<Vector> initialItems)

    {

    foreach (Vector vector in initialItems)

    {

    Add(Vector);

    }

     

    This seems odd....

     

     

    Tuesday, June 19, 2007 2:08 PM

Answers

  • Interfaces can be used as object types as well as things to be inherited from.  That's what makes them so powerful.  When using an interface as an object type, the only thing you can't do is construct it.  You can't say

    //Compiler Error
    IEnumerable<int> list_thing = new IEnumerable<int>();


    However, you're free to say...

    IEnumerable<int> list_thing = new List<int>();

    then you can do anything with list_thing that you can do with an IEnumerable<int>.

    The real advantage is that you can do something like...

    public void Fill(IEnumerable<int> toFill, int filler)
    {
        IEnumerator<int> enumer = toFill.GetEnumerator();
        enumer.Current = filler;
        while(enumer.MoveNext)
       {
           enumer.Current = filler;
       }
    }

    and you can call it with anything that inherits IEnumerable<int> like so...

    List<int> L1 = new List<int>();
    LinkedList<int> L2 = new LinkedList<int>();
    Stack<int> L3 = new Stack<int>();
                           .
                           .
                           .
    Fill(L1);
    Fill(L2);
    Fill(L3);

    By using an interface as an object type you can exploit the common functionality of objects that implement that interface.


    Tuesday, June 19, 2007 3:24 PM
  • An Interface is a contract.. So any class that implements the interface is required to implement all the methods (and properties and events) in the interface...

    In this situation the Interface is used as a parameter for a method, which means that you know that the instance that will be passed implements all the methods ( and properties and events) that are defined in the interface...)

    Code Snippet

    interface IInterface { void SayHello(); }
    class A : IInterface { public void SayHello() { Console.WriteLine(); } }
    class B : IInterface { public void SayHello() { Console.WriteLine(); } }

    class Program
    {
     static void Main(string[] args)
     {
      A aInstance =  new A();
      DoSayHello(aInstance);

     B bInstance = new B();
      DoSayHello(bInstance);
     }

     static void DoSayHello(IInterface helloSayer)
     {
      // we don't know which concrete we're going to receive.. But we do know that it implements evertything as defined in IInterface, namely: void SayHello()
      helloSayer.SayHello();
     }
    }


    HTH
    Tuesday, June 19, 2007 3:53 PM
  • Implementing an interface is not the same as inheriting from a base class (although the syntax is the same... You can implement many interfaces, but you can only inherit from 1 base class)

    Code Snippet

    interface IX { ... }
    interface IY { ... }
    class Base { ... }

    class A : Base, IX, IY { }



    This means that class A inherits all the implementation from class Base... And it provides an implementation for everything that has been defined on IX...

    Since you know this, you can use instances of class A as an instance of Base... And you can use it as an instance of IX or IY...

    Thus you can use it as following:

    Code Snippet

    IX instance = new A();    
    instance.SomeMethod() // defined on IX

    IY instance = new A();
    instance.SomeY(); // defined on IY

    Base instance = new A();
    instance.OtherMethod() // defined on Base



         
    Tuesday, June 19, 2007 6:27 PM
  • an interface reference can hold an instance to any type that implements that interface, that is where their power comes from.

     

    Now instead of saying

    string[]

    or List<string>

    or ObservableCollection<string>

     

    i can say IEnumerable<string> and use any of the above instances.

     

     

    for example if i had Sort(List<string> myList){}

     

    i'd have to write that method 2 more times to get the functionality needed for the above 3 types.

     

    however if i wrot

    Sort(IEnumerable<string> myList){}

     

    i've solved the problem with one method.

     

    how are we doing now?

    Tuesday, June 19, 2007 8:12 PM
  • One thing that might be confusing you is that your code sample won't compile. it should be

     

    Code Snippet

    public Vectors(IEnumerable<Vector> initialItems)

    {

    foreach (Vector vector in initialItems)

    {

    Add(vector);

    }

     

    You were passing a type to your Add method rather than a variable.
    Tuesday, June 19, 2007 8:38 PM

All replies

  • Interfaces can be used as object types as well as things to be inherited from.  That's what makes them so powerful.  When using an interface as an object type, the only thing you can't do is construct it.  You can't say

    //Compiler Error
    IEnumerable<int> list_thing = new IEnumerable<int>();


    However, you're free to say...

    IEnumerable<int> list_thing = new List<int>();

    then you can do anything with list_thing that you can do with an IEnumerable<int>.

    The real advantage is that you can do something like...

    public void Fill(IEnumerable<int> toFill, int filler)
    {
        IEnumerator<int> enumer = toFill.GetEnumerator();
        enumer.Current = filler;
        while(enumer.MoveNext)
       {
           enumer.Current = filler;
       }
    }

    and you can call it with anything that inherits IEnumerable<int> like so...

    List<int> L1 = new List<int>();
    LinkedList<int> L2 = new LinkedList<int>();
    Stack<int> L3 = new Stack<int>();
                           .
                           .
                           .
    Fill(L1);
    Fill(L2);
    Fill(L3);

    By using an interface as an object type you can exploit the common functionality of objects that implement that interface.


    Tuesday, June 19, 2007 3:24 PM
  • An Interface is a contract.. So any class that implements the interface is required to implement all the methods (and properties and events) in the interface...

    In this situation the Interface is used as a parameter for a method, which means that you know that the instance that will be passed implements all the methods ( and properties and events) that are defined in the interface...)

    Code Snippet

    interface IInterface { void SayHello(); }
    class A : IInterface { public void SayHello() { Console.WriteLine(); } }
    class B : IInterface { public void SayHello() { Console.WriteLine(); } }

    class Program
    {
     static void Main(string[] args)
     {
      A aInstance =  new A();
      DoSayHello(aInstance);

     B bInstance = new B();
      DoSayHello(bInstance);
     }

     static void DoSayHello(IInterface helloSayer)
     {
      // we don't know which concrete we're going to receive.. But we do know that it implements evertything as defined in IInterface, namely: void SayHello()
      helloSayer.SayHello();
     }
    }


    HTH
    Tuesday, June 19, 2007 3:53 PM
  • This is most confusing sorry, i am sure you are very clear but its hard i am new..

     

     

    what do you mean contract, i thought they expose methods that can be used... you dont write  them.

    Interfaces come from classes ,  i mean they are a collection of  methods and properties etc..

     

     

     

    When you inherit from them , you have access to these methods ? you dont implement them ?

     

    what does this mean // we don't know which concrete we're going to receive.. But we do know that it implements evertything as defined in IInterface, namely: void SayHello()
    the word concrete .

     

    Also you are defining Sayhello() in each class and then inheriting the interface in each ?

     

    When you inherit from an interface shouldnt the definition or implementation be else where prehaps in a base class ..?

     

    You could i think pass a instance of a class into a drevided class and get the same ?

    Tuesday, June 19, 2007 5:59 PM
  • Yet again some more code from a book.

     

    I note most of the code is fairly straight forward but i am unsure of the bits i put comments next to.......... this is all new to me and the example is being flashy or something....

     

     

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace ch12ex03

    {

    class Vectors : List<Vector>

    {

    public Vectors()

    {

    }

    //This constructor is  using an object type ?  cant get it..

    public Vectors(IEnumerable<Vector> initialItems)

    {

    foreach (Vector vector in initialItems)

    {

    Add(vector);

    }

    }

    public string Sum()

    {

    StringBuilder sb = new StringBuilder();

    Vector currentPoint = new Vector(0.0, 0.0);

    sb.Append("Origin");

    foreach (Vector vector in this)

    {

    sb.AppendFormat("+{0}", vector);

    currentPoint += vector;

    }

    sb.AppendFormat("= {0}", currentPoint);

    return sb.ToString();

    }

    }

    public static class VectorDelegates

    {

    public static int Compare(Vector x, Vector y)

    {

    if (x.R > y.R)

    {

    return 1;

    }

    else if (x.R < y.R)

    {

    return -1;

    }

    return 0;

    }

    public static bool TopRightQuadrant(Vector target)

    {

    if (target.Theta >= 0.0 && target.Theta <= 90.00)

    {

    return true;

    }

    else

    {

    return false;

    }

    }

    }

    }

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace ch12ex03

    {

    public class Vector

    {

    public double? R = null;

    public double? Theta = null;

    public double? ThetaRadians

    {

    get

    {

    //convert degrees to Radians

    return (Theta * Math.PI / 180.0);

    }

    }

    public Vector(double? r, double? theta)

    {

    //Normalize

    if (r < 0)

    {

    r = -r;

    theta += 180;

    }

    theta = theta % 360;

    R = r;

    Theta = theta ;

    }

    public static Vector operator +(Vector op1, Vector op2)

    {

    try

    {

    // Get (x,y) coordinates for new vector

    double newX = op1.R.Value * Math.Sin(op1.ThetaRadians.Value) + op2.R.Value * Math.Sin(op2.ThetaRadians.Value);

    double newY = op1.R.Value * Math.Cos(op2.ThetaRadians.Value) + op2.R.Value * Math.Cos(op2.ThetaRadians.Value);

    // convert to (r, theta)

    double newR = Math.Sqrt(newX * newX + newY * newY);

    double newTheta = Math.Atan2(newX, newY) * 180.0 / Math.PI;

    //return result

    return new Vector(newR, newTheta);

    }

    catch

    {

    // return null vector

    return new Vector(null, null);

    }

    }

    public static Vector operator -(Vector op1)

    {

    return new Vector(-op1.R, op1.Theta);

    }

    public static Vector operator -(Vector op1, Vector op2)

    {

    return op1 + (-op2);

    }

    public override string ToString()

    {

    // get represenation of coordinates

    string rString = R.HasValue ? R.ToString() : "null";

    string thetaString = Theta.HasValue ? Theta.ToString() : null;

    // Return (r, theta) string.

    return String.Format("({0}, {1})", rString, thetaString);

    }

    }

    }

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace ch12ex03

    {

    class Program

    {

    static void Main(string[] args)

    {

    Vectors route = new Vectors();

    route.Add(new Vector(2.0, 90.0));

    route.Add(new Vector(1.0,180.0));

    route.Add(new Vector(0.5, 45.0));

    route.Add (new Vector (2.5,315.0));

    Console.WriteLine(route.Sum());

     

    // not really explained in the book the line below..

    Comparison<Vector> sorter = new Comparison<Vector>(VectorDelegates.Compare);

    route.Sort(sorter);

    Console.WriteLine(route.Sum());

     

    //simular here 

    Predicate<Vector> searcher = new Predicate<Vector>(VectorDelegates.TopRightQuadrant);

    Vectors TopRightQuadrantRoute = new Vectors(route.FindAll(searcher));

    Console.WriteLine(TopRightQuadrantRoute.Sum());

    Console.ReadKey();

    }

    }

    }

     

    //I think the main issue is the contructor using the object type  and the two  delegate types which are nt explained well for someone new. the rest is  ok..not a great example using all this mathematic with new concepts thrown in..
    Tuesday, June 19, 2007 6:17 PM
  • Implementing an interface is not the same as inheriting from a base class (although the syntax is the same... You can implement many interfaces, but you can only inherit from 1 base class)

    Code Snippet

    interface IX { ... }
    interface IY { ... }
    class Base { ... }

    class A : Base, IX, IY { }



    This means that class A inherits all the implementation from class Base... And it provides an implementation for everything that has been defined on IX...

    Since you know this, you can use instances of class A as an instance of Base... And you can use it as an instance of IX or IY...

    Thus you can use it as following:

    Code Snippet

    IX instance = new A();    
    instance.SomeMethod() // defined on IX

    IY instance = new A();
    instance.SomeY(); // defined on IY

    Base instance = new A();
    instance.OtherMethod() // defined on Base



         
    Tuesday, June 19, 2007 6:27 PM
  • an interface reference can hold an instance to any type that implements that interface, that is where their power comes from.

     

    Now instead of saying

    string[]

    or List<string>

    or ObservableCollection<string>

     

    i can say IEnumerable<string> and use any of the above instances.

     

     

    for example if i had Sort(List<string> myList){}

     

    i'd have to write that method 2 more times to get the functionality needed for the above 3 types.

     

    however if i wrot

    Sort(IEnumerable<string> myList){}

     

    i've solved the problem with one method.

     

    how are we doing now?

    Tuesday, June 19, 2007 8:12 PM
  • Tuesday, June 19, 2007 8:13 PM
  • One thing that might be confusing you is that your code sample won't compile. it should be

     

    Code Snippet

    public Vectors(IEnumerable<Vector> initialItems)

    {

    foreach (Vector vector in initialItems)

    {

    Add(vector);

    }

     

    You were passing a type to your Add method rather than a variable.
    Tuesday, June 19, 2007 8:38 PM
  • Also, you can write your own interfaces if you'd like.  Here's a quick example of why someone might use interfaces.

    Say you want to build a graphics library, you want it to be able to draw different shapes.  You want to be able to add shapes to a "canvas" object that will be able to draw them.

    You want to be able to have circles, squares, and polygons.

    Drawing a circle is different than drawing a square or a polygon.

    What you want to avoid is having 3 different lists in your canvas object.  You don't want to have a List<Circle> circles, List<Square> squares and List<Polygon> polygons.  You also want to be able to just add a shape, not have an AddCircle(Circle toAdd) and AddSquare(Square toAdd) and AddPolygon(Polygon toAdd).

    What you can do is you could create an IDrawable interface that defines one method...

    public interface IDrawable
    {

    public void Draw();

    }

    Then Square, Circle, and Polygon all inherit IDrawable.

    Because they inherit IDrawable they all have to write a Draw method.  So when all is said and done you will have 3 implementations of the Draw method, one in Square.cs, one in Circle.cs, and one in Polygon.cs

    Now, in your canvas object, you can have just one list, List<Shape> shape_list, just one method AddShape(Shape toAdd) and when you draw the shapes, you can say...

    .
    .
    .
    foreach(Shape shape in shape_list)
    {
    shape.Draw();
    }
    .
    .
    .
    Interfaces are a lot like inheritance, but when you implement them you don't get any added functionality while implementing. (Square, Circle, and Polygon don't get any added functionality, they're just required to implement the Draw method)
    Tuesday, June 19, 2007 10:07 PM
  • lawwz, if you got your answer - please mark it as such. If not - please let us know what else you need...

     

    Thanks!

    Wednesday, June 20, 2007 5:54 PM
  • yes this is a lot of help i can see you are implementing the  sayhello()  method in both classes...
    Saturday, June 23, 2007 10:26 AM