8 Replies - 6217 Views - Last Post: 20 January 2012 - 11:24 AM Rate Topic: -----

#1 Willdvp  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 35
  • Joined: 24-October 11

IEnumerable vs IEnumerable<T>

Posted 18 January 2012 - 07:25 PM

Hi guys,

I have a doubt about use of IEnumerable and IEnumerable<T>. I searched a lot before posting here so I have some ideas in my mind, but not ther right answer.

For an example, I have three classes:
// The class which I'll have a collection
public class Person
{
     public int _id;
     
     public Person(int id)
     {
          this._id = id.
     }
};

// The collection
// The IEnumerable interface allows me to enumerate itens in a collection class
public class PersonCollection : IEnumerable
{
     public Person[] _persons;
     
     public Person(Person[] persons)
     {
          this._persons = persons;
     }

     public IEnumerator GetEnumerator()
     {
          return new PCollectionEnumerator(this);
     }
};

// Here the enumerator
publi class PCollectionEnumerator : IEnumerator
{
     public PersonCollection _col;
     public int _index;

     public PCollectionEnumerator(PersonCollection col)
     {
          this._col = col;
          this._index = -1;
     }

     public void Reset()
     {
          this._index = -1;
     }

     public object Current
     {
          get
          {
               return this._col._persons[this._index];
          }
     }

     public bool MoveNext()
     {
          this._index++;
 
          if(this._index > this._col._persons.Length)
               return false;
          else
               return true;
     }

     public class Program
     {
          public static void Main()
          {
               PersonCollection pc = new PersonCollection(new Person[]{new Person(1}, new Person(2), new Person(3));
          
               foreach(Person p in pc)
                  Console.WriteLine(p._id);
          }
     }
};



So, my question is: when I use foreach, the foreach automatically cast from object type( by the Current property ) into Person type?

So, when I use generic interfaces like IEnumerable<T> and IEnumerator<T>, the foreach do not need to cast( because IEnumerator.Current returns a Person object), "improving" the performance and type-safe?

Thank you guys :*

ps: Sorry about my english, I'm learning :B

Is This A Good Question/Topic? 0
  • +

Replies To: IEnumerable vs IEnumerable<T>

#2 RexGrammer  Icon User is offline

  • Coding Dynamo
  • member icon

Reputation: 181
  • View blog
  • Posts: 777
  • Joined: 27-October 11

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 06:01 AM

I've seen you have ; at the end of your class declaration. From this I guess that you haul from the world of C++, am I right?

In C# you don't need to put ; at the end of class declarations, it will produce an error.

I also saw a typo: instead of public it was publi

Here's your code with a few minor fixes. No logic changed just removed the ; and fixed a typo.
Spoiler


What is exactly the error you're getting?

This post has been edited by RexGrammer: 19 January 2012 - 06:25 AM

Was This Post Helpful? 0
  • +
  • -

#3 janne_panne  Icon User is offline

  • WinRT Dev
  • member icon

Reputation: 429
  • View blog
  • Posts: 1,047
  • Joined: 09-June 09

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 06:22 AM

@RexGrammer: He wasn't having any errors, at least based on his questions at the end.

@Willdvp: You are right. Foreach loop will perform a cast if you use non-generic IEnumerator. It will also be type-unsafe as you said. For example, you can try to do this:
            PersonCollection pc = new PersonCollection(new Person[] { new Person(1), new Person(2), new Person(3) });

            foreach (string p in pc)
                Console.WriteLine(p);


Compiler won't say a thing but when you execute the code, it will throw an exception.

When using generic IEnumerable<T> and IEnumerator<T>, compiler will already give you an error that type Person can't be converter to string.

Like RexGrammer pointed out, you might come from C++ environment (although having ; at the end of a class won't throw an error) and in that case I would like you to think if you actually need your own implementation of IEnumerable and IEnumerator. There are already generic implementation available like List<T> which is all you need in most cases. But of course you can implement them just for practice if not anything else.
Was This Post Helpful? 1
  • +
  • -

#4 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,412
  • Joined: 29-May 08

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 06:57 AM

IEnumerable could return any type and then you have to cast it the correct type.
Say you have a collection integers, it could contain a Can<Whoop_Ass> because Object is inherited by all.

IEnumerable<T> can only return types that are or inherit T. Plus no casting.
Say you have Basket<Fruit> it can not contain a Can<Whoop_Ass>
Was This Post Helpful? 0
  • +
  • -

#5 Willdvp  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 35
  • Joined: 24-October 11

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 06:59 AM

@RexGrammer: Yes, I come from C++, and the ; at the end of classes declaration is just a habit :B Thank you for the fixes.

@janne_panne: That's right, I was in doubt if foreach automatically cast from object(when non-generic enumerator), to the right type, I'm learning C# by now, and practicing some interface implementations. Thank you for the explanation.

@AdamSpeight2008: I'm a bit confused with your answer, but thank anyway man :D

This post has been edited by Willdvp: 19 January 2012 - 07:02 AM

Was This Post Helpful? 0
  • +
  • -

#6 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,412
  • Joined: 29-May 08

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 07:36 AM

OK them, I let the code do the talking for me.
 public class WhoopAss : System.Collections.IEnumerable
{
    int[] m_Nums = { 1, 2, 3, 4, 5, 6 };
    public System.Collections.IEnumerator GetEnumerator()
    {
        for (int i = 0; i < m_Nums.Length; i++)
        {
            yield return m_Nums[i];
        }
        yield return "WhoopAss";
    }
}   


Example program
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var n in d)
            { t += (int)n; }
            Console.WriteLine(t);
        }
    }


Was This Post Helpful? 0
  • +
  • -

#7 Willdvp  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 35
  • Joined: 24-October 11

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 02:08 PM

@AdamSpeight2008: Thank you for the explanation, but I don't know what yield does(yet), I'll search something about, remember, I'm still a beginner :B
Was This Post Helpful? 0
  • +
  • -

#8 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2241
  • View blog
  • Posts: 9,412
  • Joined: 29-May 08

Re: IEnumerable vs IEnumerable<T>

Posted 19 January 2012 - 09:58 PM

My point isn't about yield but the type Object. Run an find out.
Was This Post Helpful? 0
  • +
  • -

#9 RexGrammer  Icon User is offline

  • Coding Dynamo
  • member icon

Reputation: 181
  • View blog
  • Posts: 777
  • Joined: 27-October 11

Re: IEnumerable vs IEnumerable<T>

Posted 20 January 2012 - 11:24 AM

Quote

The yield keyword signals to the compiler that the method in which it appears is an iterator block. The compiler generates a class to implement the behavior that is expressed in the iterator block. In the iterator block, the yield keyword is used together with the return keyword to provide a value to the enumerator object. This is the value that is returned, for example, in each loop of a foreach statement. The yield keyword is also used with break to signal the end of iteration. For more information about iterators, see Iterators (C# Programming Guide). The following example shows the two forms of the yield statement.

Src:
yield (C# Reference)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1