Microsoft KB Archive/816194

= How to make a Visual C++ .NET or Visual C++ 2005 class usable in a foreach statement =

Article ID: 816194

Article Last Modified on 5/21/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Visual C++ 2005 Express Edition
 * Microsoft Visual C++ .NET 2003 Standard Edition
 * Microsoft Visual C++ .NET 2002 Standard Edition

-







For a Microsoft Visual Basic .NET version of this article, see 322025.



For a Microsoft Visual C# .NET version of this article, see 322022.

This article refers to the following Microsoft .NET Framework Class Library namespaces:
 * System
 * System::Collections

IN THIS TASK

 * SUMMARY
 * Requirements
 * Use the IEnumerator interface
 * Use the IEnumerable interface
 * Decide whether to use the IEnumerator interface or the IEnumerable interface
 * Demonstrate how to use the IEnumerable interface and the IEnumerator interface
 * REFERENCES



SUMMARY
This step-by-step article describes how to use the IEnumerable interface and the IEnumerator interface to create a class in Microsoft Visual C++ .NET or in Microsoft Visual C++ 2005. You can use the class in a foreach statement in Microsoft Visual C#, in Microsoft Visual Basic .NET, or in Microsoft Visual Basic 2005. The IEnumerable interface and the IEnumerator interface are frequently used together. Although the interfaces have similar names, the interfaces have different purposes.

Back to the top

Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
 * Visual C++ .NET 2002, Visual C++ .NET 2003, or Visual C++ 2005
 * Microsoft .NET Framework 1.0, 1.1, or later

This article assumes that you are familiar with the following topics:
 * An intermediate understanding of Visual C++ programming concepts

Back to the top

Use the IEnumerator interface
The IEnumerator interface provides iterative capability for a collection that is internal to a class. The IEnumerator interface requires that you implement three methods. Each method has its own purpose.
 * The MoveNext method increments the collection index by 1 and returns a Boolean value that indicates whether the end of the collection has been reached.
 * The Reset method resets the collection index to its initial value of -1. This invalidates the enumerator.
 * The get_Current method returns the current object at [position].

See the following code sample: bool IEnumerator::MoveNext {   position++; return (position < carlist->Length); }

void IEnumerator::Reset {   position = 0; }

Object* IEnumerator::get_Current {   return (carlist[position]); } Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile the previous code sample. To add the common language runtime support compiler option in Visual C++ 2005, follow these steps:
 * 1) Click Project, and then click   Properties.

Note  is a placeholder for the name of the project.
 * 1) Expand Configuration Properties, and then click General.
 * 2) Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting in the right pane, click Apply, and then click OK.

For more information about the common language runtime support compiler option, visit the following Microsoft Web site:

/clr (Common Language Runtime Compilation)

http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

Back to the top

Use the IEnumerable interface
The IEnumerable interface provides support for the foreach iteration. The IEnumerable interface requires that you implement the GetEnumerator method.

See the following code sample: IEnumerator* IEnumerable::GetEnumerator {   return new MyEnumerator(carlist); } Back to the top

Decide whether to use the IEnumerator interface or the IEnumerable interface
The IEnumerator interface provides iteration over a collection-type object in a class. The IEnumerable interface permits enumeration by using a foreach loop. However, the GetEmunerator method of the IEnumerable interface returns an IEnumerator interface. Therefore, to implement the IEnumerable interface, you must also implement the IEnumerator interface. If you do not implement the IEnumerator interface, you cannot cast the return value from the GetEnumerator method of the IEnumerable interface to the IEnumerator interface.

Therefore, when you try to decide whether to use the IEnumerator interface or the IEnumerable interface, you must remember that the IEnumerable interface requires that the class implement the IEnumerator interface. If you want to provide support for foreach, you must implement both interfaces.

Back to the top

Demonstrate how to use the IEnumerable interface and the IEnumerator interface
The following steps demonstrate how to use these interfaces. In the following steps, the IEnumerator interface and the IEnumerable interface are used in a class that is named cars. The cars class has an internal array of car objects. Client applications can enumerate through this internal array by using a foreach construct because of the implementation of these two interfaces. Because Visual C++ .NET does not support a foreach construct, Visual C# .NET is used as an example to demonstrate the use of the cars class in a foreach construct. Alternatively, you can use Visual Basic .NET for the same purpose.  To create a Console Application project in Visual C# .NET or in Visual C# 2005, follow these steps:  Start Microsoft Visual Studio .NET 2002, Visual Studio .NET 2003, or Microsoft Visual Studio 2005. On the File menu, point to New, and then click Project.

The New Project dialog box appears. Under Project Types, click Visual C# Projects.

Note In Visual Studio 2005, click Visual C# under Project Types. Under Templates, click Console Application.

Note In Visual Studio 2005, click Console Application under Templates. In the Name box, type ConsoleEnum, and then click OK.</li></ol> </li>  In Microsoft Solution Explorer, rename the Class1.cs file to Host.cs, and then replace the code in the Host.cs file with the following code: using System; using carsnamespace; using carnamespace;

namespace ConsoleEnum {   class host {       [STAThread] static void Main(string[] args) {           cars C = new cars; Console.WriteLine(&quot;\nInternal Collection (Unsorted - IEnumerable,Enumerator)\n&quot;); foreach(car c in C)               Console.WriteLine(c.Make + &quot;\t\t&quot; + c.Year); Console.ReadLine; }   } } </li> On the File menu, point to Add Project, and then click New Project.</li> Under Project Types, click Visual C++ Projects.</li> If you are using Visual Studio 2005, click C++ Class under Templates.

If you are using Visual Studio .NET 2003, click Class Library (.NET) under Templates.

If you are using Visual Studio .NET 2002, click Managed C++ Class Library under Templates.</li> In the Name box, type Car, and then click OK.</li> In Solution Explorer, expand the Header Files folder in the Car project folder.</li> Double-click the Car.h file to open the file in the Code window.</li>  Replace the code in the Car.h file with the following code: // Car.h
 * 1) pragma once

using namespace System; using namespace System::Collections;

namespace carnamespace {   public __gc class car {   private: int year; String * make;

public: car(String *Make,int Year) {           make = Make; year = Year; }

__property String* get_Make {           return make; }       __property void set_Make(String* Make) {           make = (Make); }       __property int get_Year {            return year; }       __property void set_Year(int Year) {           year = Year; }   }; } </li> In Solution Explorer, right-click the Car project folder, and then click Build.

This builds the Car Class Library and then creates the Car.dll file in the output folder.</li> Repeat step 3 to step 6 to add another new project that is named Cars.</li> In Solution Explorer, expand the Header Files folder in the Cars project folder.</li> Double-click the Cars.h file to open the file in the Code window.</li>  Replace the code in the Cars.h file with the following code: // Cars.h
 * 1) pragma once

using namespace System; using namespace System::Collections; //Comment the following #using statement for Visual Studio .NET 2003. using namespace carnamespace;
 * 1) using &quot;Absolute Path of Car.dll&quot;

namespace carsnamespace { public __gc class cars : public IEnumerator, public IEnumerable {   private: car *carlist[]; static int position = -1;

public: cars {           carlist = new car *[6]; carlist[0]= new car(S&quot;Ford&quot;,1992); carlist[1]= new car(S&quot;Fiat&quot;,1988); carlist[2]= new car(S&quot;Buick&quot;,1932); carlist[3]= new car(S&quot;Ford&quot;,1932); carlist[4]= new car(S&quot;Dodge&quot;,1999); carlist[5]= new car(S&quot;Honda&quot;,1977); }       //IEnumerator and IEnumerable require these methods. IEnumerator* IEnumerable::GetEnumerator {           return __try_cast<IEnumerator*>(this); }

//IEnumerator bool IEnumerator::MoveNext {       position++; return (position < carlist->Length); }

//IEnumerator void IEnumerator::Reset {           position = 0; }

//IEnumerator Object* IEnumerator::get_Current {           if (position < 0 || position == carlist->Length) throw new InvalidOperationException; return (carlist[position]); }

}; } Note In the code that you added,   is a placeholder for the absolute path that includes the file name of the Car.dll file. </li>  If you are using Visual Studio .NET 2003 or Visual Studio 2005, locate the following line in the code that you added in step 14, and then comment the next line after this location: //Comment the following #using statement for Visual Studio .NET 2003 or Visual Studio 2005. </li> If you are using Visual Studio .NET 2003 or Visual Studio 2005, you must add a reference to the Car.dll file that you created in step 10. To do this, follow these steps: <ol style="list-style-type: lower-alpha;"> <li>In Solution Explorer, right-click the Cars project folder, and then click Add Reference.</li> <li>In the Add Reference dialog box, click the Projects tab.</li> <li>In the projects list, double-click Car, and then click OK.</li></ol> </li> <li>In Solution Explorer, right-click the Cars project folder, and then click Build.

This builds the Cars Class Library and then creates the Cars.dll file in the output folder.</li> <li>To use the Car Class Library and the Cars Class Library in the Visual C# .NET Console Application project, you must add a reference to the Car.dll file and to the Cars.dll file. To do this, follow these steps: <ol style="list-style-type: lower-alpha;"> <li>In Solution Explorer, right-click the ConsoleEnum project folder, and then click Add Reference.</li> <li>In the Add Reference dialog box, click the Projects tab.</li> <li>In the projects list, double-click Car.</li> <li>In the projects list, double-click Cars, and then click OK.</li></ol> </li> <li>In Solution Explorer, right-click the ConsoleEnum project folder, and then click Set as StartUp Project.</li> <li>Press CTRL+SHIFT+S to save all the projects.</li> <li>Press CTRL+SHIFT+B to build the solution.</li> <li> Press CTRL+F5 to run the project.

Notice that the following output appears in the Console window: Internal Collection (Unsorted - IEnumerable,Enumerator)

Ford           1992 Fiat           1988 Buick          1932 Ford           1932 Dodge          1999 Honda          1977 </li></ol>

Back to the top

<div class="references_section">