Changes from C ++ to C # Notes (3)

Source: Internet
Author: User

Introduction: every 10 years or so, programmers need to spend a lot of time and energy learning new programming technologies. In 1980s, it was Unix and C, and in 1990s it was Windows and C ++. Now it has reached Microsoft's. NETFramework and C #. Although new technologies need to be learned, the benefits are far higher than the labor cost. Fortunately, the analysis and design of most projects using C # And. NET have no essential changes in C ++ and Windows. In this article, I will introduce how to make a leap from C ++ to C.

Series of articles: [changes from C ++ to C # Notes (1) (2) (3) (4)]

IEnumerable Interface

Return to the example above. As in an ordinary array, using the foreach-loop structure can print the strings in the ListBoxTest class, and implement the IEnumerable interface in the class, this is done implicitly by the foreach-loop structure. The IEnumerable interface can be implemented in any class that supports enumeration and foreach-loop loops.

The IEnumerable interface has only one method GetEnumerator, and its task is to return a special implementation of IEnumerator. From the syntax perspective, the Enumerable class can provide an IEnumerator.


Figure5ListBoxClass
UsingSystem;
// Simplified ListBox control
PublicclassListBoxTest
{
// Initialize the ListBox with a string
PublicListBoxTest (paramsstring [] initialStrings)
{
// Allocate space for strings
MyStrings = newString [256];
// Copy the string to the constructor
Foreach (stringsininitialStrings)
{
MyStrings [myCtr ++] = s;
}
}
// Add a string at the end of ListBox
PublicvoidAdd (stringtheString)
{
MyStrings [myCtr ++] = theString;
}
Publicstringthis [intindex]
{
Get
{
If (index <0 | index> = myStrings. Length)
{
// Process problematic Indexes
}
ReturnmyStrings [index];
}
Set
{
MyStrings [index] = value;
}
}
// Returns the number of strings.
PublicintGetNumEntries ()
{
ReturnmyCtr;
}
Privatestring [] myStrings;
PrivateintmyCtr = 0;
}
PublicclassTester
{

StaticvoidMain ()
{
// Create a new list and initialize it.
ListBoxTestlbt = newListBoxTest ("Hello", "World ");
// Add some new strings
Lbt. Add ("Who ");
Lbt. Add ("Is ");
Lbt. Add ("John ");
Lbt. Add ("Galt ");
Stringsubst = "Universe ";
Lbt [1] = subst;
// Access all strings
For (inti = 0; I {
Console. WriteLine ("lbt [{0}]: {1}", I, lbt [I]);
}
}
}


Enumerator must implement the IEnumerator method, which can be directly implemented through a container class or an independent class. The latter method is often used because it can encapsulate this task in the Enumerator class, without confusing the container class. We will add the Enumerator class to ListBoxTest in the above Code, because the Enumerator class is for our container class (because ListBoxEnumerator must understand many situations of ListBoxTest ), we will make it public in ListBoxTest. In this example, ListBoxTest is defined to complete the IEnumerable interface. The IEnumerable interface must return an Enumerator.


PublicIEnumeratorGetEnumerator ()
{
Return (IEnumerator) newListBoxEnumerator (this );
}


Note that the method passes the current ListBoxTest object (this) to Enumerator, which enables Enumerator to enumerate the elements in the specified ListBoxTest object.

The implementation of this type of Enumerator is implemented as ListBoxEnumerator, which is defined as a private class in ListBoxTest, which is quite simple.

The enumerated ListBoxTest is passed to the constructor as a parameter, and the ListBoxTest is assigned to the variable myLBT. The constructor also sets the member variable index to-1, indicating that the object enumeration has not started.


PublicListBoxEnumerator (ListBoxTesttheLB)
{
MyLBT = theLB;
Index =-1;
}


The MoveNext method adds 1 to the index and ensures that the boundary of the enumerated object is not exceeded. If the boundary is exceeded, false is returned; otherwise, true is returned.


PublicboolMoveNext ()
{
Index ++;
If (index> = myLBT. myStrings. Length)
Returnfalse;
Else
Returntrue;
}


The function of Reset is to set the index value to-1.

Current returns the recently added string, which is an arbitrary setting. In other classes, Current can be meaningful to the designer. No matter how it is designed, each enumeration method must be able to return the current member.


PublicobjectCurrent
{
Get
{
Return (myLBT [index]);
}
}

Call the foreach loop structure to obtain the enumeration method and use it to process each member in the array. Since the foreach loop structure will display every string, no matter whether we have added a meaningful value or not, we will change the initialization of myStrings to eight entries to ensure that the display is easy to process.


MyStrings = newString [8];


Use Basic Class Library

In order to better understand the differences between C # And C ++ and the changes in solution methods, let's look at a simple example. We will create a class to read text files and display their content on the screen. I will make it a multi-threaded program so that other work can be done while reading data from the disk.

In C ++, we may create a thread for reading files and another thread for other jobs. These two threads will run independently, however, they may need to be synchronized. In C #, we can also do the same job. Because the. NET Framework provides a powerful asynchronous I/O mechanism, we will save a lot of time when writing threads.

Asynchronous I/O support is built in CLR and is almost as simple as using a normal I/O Stream class. At the beginning of the program, we first notify the compiler that we will use objects in many namespaces in the program:


UsingSystem;
UsingSystem. IO;
UsingSystem. Text;


The program contains System and does not automatically contain all its sub-namespaces. You must use the using parameter to explicitly include each sub-namespace. We will use the I/O Stream class in the example. Therefore, we need to include the System. IO namespace. We also need the System. Text namespace to support the ASCII encoding of the byte stream.

As the. NET architecture completes most of the work, the steps required to write this program are quite simple. We will use the Stream inread method of the Stream class, which provides the asynchronous I/O function to read data into a buffer. When the buffer can be processed, the corresponding processing program is called.

We need to use a byte array as the proxy for the buffer and call-back methods, and define the two as private member variables of the driver class.


PublicclassAsynchIOTester
{
PrivateStreaminputStream;
Privatebyte [] buffer;
PrivateAsyncCallbackmyCallBack;


InputStream is a Stream type variable. We will call the BeginRead Method for it. The proxy is very similar to the pointer of a member function. Proxy is the first element of C.

When the buffer is filled with files on the disk,. NET calls the proxy method to process the data. While waiting to read data, we can ask the computer to do other work. (In this example, an integer variable is increased from 1 to 50000, but in the actual application, we can allow computers to interact with users or do other meaningful work .)

In this example, the proxy is defined as AsyncCallback, which is required by the Stream BeginRead method. The definition of AsyncCallback type proxy in System space is as follows:


PublicdelegatevoidAsyncCallback (IAsyncResultar );


This proxy can be associated with any method that returns the void type value and uses the IAsyncResult interface as a parameter. When this method is called, CLR can pass the IAsyncResult interface object as a parameter at runtime. We need to define this method as follows:


VoidOnCompletedRead (IAsyncResultasyncResult)


Connect to the proxy in the constructor:


AsynchIOTester ()
{
???
MyCallBack = newAsyncCallback (this. OnCompletedRead );
}


The code above assigns the proxy instance to the member variable myCallback. The following is the detailed working principle of all programs. In the Main function, an instance of the class is created and run:


 

PublicstaticvoidMain ()
{
AsynchIOTestertheApp = newAsynchIOTester ();
TheApp. Run ();
}


The new parameter can start the constructor. In the constructor, open a file and obtain a Stream object. Then allocate space in the buffer and associate it with the callback mechanism.


AsynchIOTester ()
{
InputStream = File. OpenRead (@ "C: MSDNfromCppToCS.txt ");
Buffer = newbyte [BUFFER_SIZE];
MyCallBack = newAsyncCallback (this. OnCompletedRead );
}


In the Run method, we call BeginRead, which reads files asynchronously.


InputStream. BeginRead (
Buffer, // store the result
0, // offset
Buffer. Length, // The number of bytes in the buffer.
MyCallBack, // callback proxy
Null); // local object


In this case, we can do other work.


For (longi = 0; I <50000;

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.