Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

C#: Why Do We Need Another Language? : Page 4

New computer languages are rare and successful ones are rarer still, yet Microsoft decided to create a new language to go along with the .NET Developer Platform. Why weren't existing languages good enough?


advertisement
XML Doc Comments
Java provides a feature called JavaDoc, where programmers can add documentation to their code as they write it. C# programmers can do the same thing using XML Doc Comments:

/// <summary> /// The distance between two points /// </summary> /// <param name="pt1">Point 1</param> /// <param name="pt2">Point 2</param> /// <returns>The distance</returns> public static float Distance( MyPointF pt1, MyPointF pt2) { MyPointF delta = pt1 - pt2; return (float) Math.Sqrt(delta.X * delta.X + delta.Y * delta.Y); }

The comments are written as XML and are extracted out to a separate XML file as part of the compilation process. Any XML can be used as long as it's well-formed, so it's easy to support company-specific information. The generated XML can be combined with information obtained through reflection to generate documentation.

Additionally, the Visual Studio .NET IntelliSense engine presents this information as part of the coding process.

User-Defined Primitive Types
Most programming languages only supply a basic set of predefined types—types such as int, short, float and double. Using such types is second nature for most programmers, so they would have no trouble understanding the following:

int startValue = 55; int endValue = 88; for (int i = startValue; i != endValue; i++) { int result = i * i + 35; Console.WriteLine("{0} {1}", i, result); } Console.WriteLine("start, end: {0} {1}", startValue, endValue);

It's very clear what this code does. If you need to implement the same algorithm with numbers of unlimited precision, you could use a Bignum class and write the following code:



Bignum startValue = new Bignum(55); Bignum endValue = new Bignum(88); for (Bignum i = startValue; i != endValue; i = i.add(new BigNum(1))) { Bignum result = i.multiply(i).add(new Bignum(35)); Console.WriteLine("{0} {1}", i, result); } Console.WriteLine("start, end: {0} {1}", startValue, endValue);

There are several issues with this code. The first is that it's considerably more complex than the first version, which makes it more difficult to write, code review and maintain. Bignums don't work any differently than integers but in using them we're forced to write drastically different code.

The second issue is that there are two subtle bugs in the Bignum version of the code. Can you find them?

The first bug is in the completion test. This statement is a problem:

i != endValue

Since Bignum is a class, this statement doesn't compare the values of i and endValue, it compares the references. Since they're not the same instance, this statement is never true.

The second bug is in the initialization of the For loop. The following statement doesn't work the way the same statement in the int version does:

Bignum i = startValue;

Since Bignum is a class, variables of type Bignum perform reference assignment and, after execution of this statement, both i and startValue refer to the same instance. The assignment to i also changes the value of startValue, so startValue ends up being overwritten.

Writing types such as Bignum isn't an everyday programming task, but it is important that such types are easy to use and behave the way that programmers expect them to. C# provides three features that can make Bignum behave the same way int does.

First, C# allows the user to author types that have value semantics, just like the predefined types do. In the .NET world, these are known as value types, which are defined in C# using the struct keyword. Value types are allocated on the stack or as part of other objects and have value semantics. A Bignum type written as a value type prevents the bug that we had in our version. It also provides better efficiency if we have an array of those types as there isn't a separate heap allocation for each element.

The second feature that helps out is user-defined conversions. It's always a safe operation to create a Bignum from an int. Adding a user-defined conversion enables us to simplify the code. Instead of writing:

Bignum startValue = new Bignum(55);

We can simply write:

Bignum startValue = 55;

Being able to create new primitives enables programmers to leverage their existing knowledge resulting in superior code.
The final feature to give us "int fidelity" is operator overloading. Rather than calling methods to perform operations, we can use the existing mathematic operators. Using these three features, the code that we write for Bignum is identical to the code for int:

Bignum startValue = 55; Bignum endValue = 88; for (Bignum i = startValue; i != endValue; i++) { Bignum result = i * i + 35; Console.WriteLine("{0} {1}", i, result); } Console.WriteLine("start, end: {0} {1}", startValue, endValue);

Being able to create new primitives enables programmers to leverage their existing knowledge resulting in superior code. In fact, the System.Decimal type in C# is implemented as a user-defined value type.


Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date