Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using foreach to enumerate objects 1

Status
Not open for further replies.

Pumzy

Programmer
Nov 20, 2003
13
JP
hello people!
i want to find a way to enumerate my objects (such as textboxes, buttons, etc) in my form using foreach statement.
i don't know how to do this in C#. can anyone help? tnx. happy new year!!!

KDjLogan
 
System.Windows.Forms.Form frm = new System.Windows.Forms.Form ();
//... Add controls in the frm
// Enumerate the controls

foreach (Control ctrl in frm.Controls)
{
// ... ctrl
Type t = ctrl.GetType();
// ...
}

-obislavu-
 
THANKS OBISLAVU DUDE! TIL NEXT TIP... :)

KDjLogan
 
Pumzy -
FYI, this can be done to any object that implements the IEnumerable interface. If you look in the help, you'll find a list of objects on which you can do foreach(){}. It goes from Array to XmlSchemaCollection.

You can implement this interface in your classes too:
Code:
using System.Collections;
using System.Drawing;

class Triangle : IEnumerable
{
   public Point A, B, C;

   // declare method required by IEnumerable
   public IEnumberator GetEnumerator()
   {
      return new PointEnumerator(this);
   }

   // Inner class implements IEnumerator interface
   private class PointEnumerator : IEnumerator
   {
      private int position = -1;
      private Triangle t;

      // constructor
      public PointEnumerator(Triangle t)
      {
         this.t = t;  // make a local copy of the Triangle object
      }

      // Declare the public method required by IEnumerator
      public bool MoveNext()
      {
         if (position < (3 - 1) // three points in triangle, 
                                // subtract one for starting at 0
            position++;
            return true;
         }
         else
         {
            return false;
         }
      }

      // declare the public method required by IEnumerator
      public void Reset()
      {
         position = -1;
      }

      // declare the public property required by IEnumerator
      public object Current
      {
         get
         {
            switch (position)
            {
               case 0:
                  return t.A.ToObject();
                  break;
               case 1:
                  return t.B.ToObject();
                  break;
               case 2:
                  return t.C.ToObject();
                  break;
               default:
                  return null;
                  break;
            }
         }
      }
   }      
}
What this code does is declare a class named Triangle that implements the IEnumerable interface. It will allow you to go through the points of the triangle using the foreach(){} operator.

IEnumerable uses another interface named IEnumerator, which does all the dirty work -- it requires you to implement two methods and a property. The methods reset the position to the beginning, and move the position to the next point. The property retrives whatever Point is current.

This is actually a good example for someone new to C# and .NET, as it illustrates some cool features of the language -- private classes (classes which are only visible inside their containing class), interfaces (programming by contract -- you promise to write code which will implement the interface), and passing a reference to an object to another object via it's constructor method.

Some notes about doing this: The Point object is a value type, not a reference type (meaning it's a struct, not a class). When the Current property returns one, it has to call ToObject (since Current demands that it be an object). This involves what's known as &quot;boxing&quot; the Point object, which is converting the value type to a reference type. This is inherently slow, as the calling function would have to cast it (it's now an Object) back into a Point datatype before accessing the .x and .y properties of a Point. Which brings up another point (pun intended) -- IEnumerator only knows about Objects. Which means you could (if you were clever or dumb, depending on your viewpoint) cast into another datatype other than a Point. When the next version of .NET comes out (Whidbey) you will be able to use Generics, which prevent this feature/problem.

Chip H.


If you want to get the best response to a question, please check out FAQ222-2244 first
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top