Neat Things


foreach

Like Visual Basic .NET and Perl, C# provides a foreach statement, which can be used to enumerate over objects that implement IEnumerable .

Design Choice 1

When writing containers that store value types, using the IEnumerable design pattern has an unfortunate side effect. Because IEnumerable.GetEnumerator returns an IEnumerator and IEnumerator.Current is of type object , the only way to return values from an enumerator is as an object. For value types, this means that the Current property boxes the value type and then returns it to the client, which immediately unboxes it. This boxing and unboxing is unfortunate from a performance standpoint.

To get around this problem, C# supports an alternative way of doing enumerators. If a class returns a type from GetEnumerator() that matches IEnumerator exactly except in terms of the type of the Current property, the compiler will use that class for enumeration.

To interoperate with other languages, containers that take this approach would typically provide a strongly typed version for use from within C# and implement IEnumerable privately for interoperability with other .NET languages.

Design Choice 2

In the foreach statement, there is an "implicit explicit" conversion. For example, when the user writes

 foreach (string s in listItems) 

there is an implicit explicit conversion from the type of IEnumerator. Current to the type declared in the foreach statement. As the target type must be specified explicitly in the foreach statement and there is no reasonable cast syntax, the simplification of having this happen automatically without a cast is justified.

switch on String

To support a common user scenario, C# allows the user to write a switch statement based on string values (see Listing B.2).

Listing B.2
 switch (command) {     case "run":         RunAway();         break;     case "stop":         StopDoingThat();         break;     case default:         NotMyFault();         break; } 

For small numbers of cases, the compiler will take advantage of the string interning [9] feature during runtime. The compiler calls String.IsInterned() with the switch variable and returns a reference to the interned string, if the string was previously interned, or null. If the return value is null, the string can't be any of the case labels, because, as constant strings, they're all interned. If the return value isn't null, the returned string instance is compared with the instances of each case label to see if there is a match.

[9] String interning is the method the runtime environment uses to keep a pool of constant strings. There is only one instance of a specific string in the intern pool.

For large numbers of cases, the compiler switches to a hash table implementation.

params Arrays

One problem faced when writing libraries is dealing with methods that can take a variable number of parameters. The simplest way to deal with this issue is to write overloaded methods :

 int Process(object param1);  int Process(object param1, object param2); int Process(object param1, object param2, object param3); 

Unfortunately, this approach doesn't work very well if you need to pass 12 parameters. Another option is to write an overload that accepts an array:

 int Process(object[] values); 

That allows the user to pass any number of parameters, but the user must now write code like the following:

 Process(new object[] { 133, 13333, "Hi", "There", "Mom"}); 

This code is not only ugly; it's different than other usages of Process() , so it complicates the user model.

In C#, if the user decorates the definition of the function with the params keyword,

 int Process(params object[] values); 

the compiler will take a call like

 Process(133, 13333, "Hi", "There", "Mom"); 

and automatically generate the temporary object array for the user.

Because this transformation adds some overhead, a typical design pattern is to write specific overloads for the most common cases (often for a maximum of three parameters), and then use parameters to handle any calls with more than three parameters.

XML Comments

In addition to the normal C++-style comments, C# allows the user to write comments in XML. Such comments are written using three slashes :

 /// <summary>  /// Square a number /// </summary> /// <return>The squared number</return> public double Square(double number) 

When code with XML comments is compiled with the /DOC compiler switch, the compiler ensures that the XML comments are valid XML, validates any parameter names mentioned, and writes the XML comments to an output file. For each block of XML that is written, the compiler will generate a globally unique name for the element with which the XML is associated. A post-processing program can then reflect over an assembly, generate information about the classes, and integrate the XML comments to generate the final documentation. Additionally, the Visual Studio IDE presents the XML comment information in IntelliSense if the generated XML file has the same name as the assembly and lives in the same directory.



Programming in the .NET Environment
Programming in the .NET Environment
ISBN: 0201770180
EAN: 2147483647
Year: 2002
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net