I happened across a posting
earlier today which contrasted Java and Ruby code snippets. The
intent of the post (an enjoyable read, by the way) was to
demonstrate the elegance of Ruby's simple, compact syntax, using
the more verbose Java as a counter-example.

This post, on the other hand, attempts to use some of C#'s
more recent features to demonstrate how static languages are
closing the "elegance" gap (for lack of a better term) which the
original poster demonstrated.

Extension Methods

The author opens with this example:

10.times { print "ho" }

The author of the post implies that this is possible because
Ruby treats 10 as an object, while Java does
not. The same is true in C# (integers do not inherit from
Object, and are "primitive"); however, with
the help of extension methods in C# 3.0 I can very closely emulate
Ruby's syntax:

10.Times(i => Console.Write("ho"));

The integer here is never boxed -- this is just syntactic
sugar for explicitly calling the extension method with an explicit
argument. Here's the entire source of the extension method:

Collections

The next section of the post contrasts the collection syntax
... the author argues in favor of Ruby on a number of points here,
none of which I wholeheartedly agree on (I prefer to be explicit
with collection choice and usage).

Initializer syntax is singled out for non-array types
(fairly). This is another problem nicely solved in C# 3.0 by way
of collection initializers. The following snippets both result in
a strongly typed int array of 3 numbers,
with the second array coming by way of a generic
collection:

new int[] { 1, 2, 3 };
new List<int> { 1, 2, 3 }.ToArray();

The author next argues for a more complete collection of
methods on various collections, including dynamic array
growth. Some of this could be accomplished with further extension
methods, but I personally feel that Push
and Pop belong on
Stack, not Array, so
I'm not going to bother implementing those.

In terms of dynamic array growth, that is handled quite
nicely by collection classes which are optimized for that case
(List<T> et al). Array-like syntax is
supported (as it has been since C# 1.0), but my personal
preference is to call an Add method when
I want to add something.

File I/O and Regular Expressions

The last language-level feature the author contrasts is
parsing sentences containing the work "Ruby" from a text
file:

Summary

The point of this post was not to imply that C# is better
than Ruby, or Java for that matter. I simply wanted to point out
that brevity and elegance are not the exclusive domain of dynamic
languages. "Syntactic sugar" can go a long ways, without requiring
fundamental changes to a language or its runtime. C# 3.0 is a
particularly relevant example, given that it runs atop the 2.0 CLR
despite all of its syntactic sugar.

If you're interested in toying around with the examples
cited in the program listings above, I've attached the sample code
to this post. To use it, install the LINQ
CTP and run MSBuild from a command prompt.

Attachments

In the .NET Framework 2.0,
System's
Console class was enhanced to provide a
variety of new functionality. The ability to trap typed keys was
introduced, as well as explicit control for cursor positioning. In
a nutshell, managed developers were given just enough control over
the system console to read masked input, which is what this post
is about.

The following sections contain the details of reading masked
input (think passwords) from the console.

Choosing a String Format

Also introduced in the 2.0 version of the Framework was the
SecureString class, which wraps a string
buffer that is encrypted in memory and can be freed
predictably. The downside is that it's a bit more complicated to
use, and it is only usable in a small number of standard APIs
(Process.Start
being the most relevant). Still, it's the best choice for reading
a password to be fed into one of the API methods which support
it.

It is also quite useful to obtain a normal
System.String
instance for other use cases. If you're collecting a password to
send to an FTP server, for example, it's quite useless in the
context of overall system security to trouble yourself storing the
password encrypted in memory (the password is sent in clear text
via FTP's control connection).

Rather than limit the API to one or the other, I decided to
add support for both. The code which collects input from the
console operates using the following interface abstraction:

Reading Console Input

The only method used for receiving input from the console is
Console.ReadKey. An
overload of this method enables the caller to trap input -- that
is, read a character without it being automatically echoed to the
console by the framework. When the user presses a character key,
for example, we append it to the buffer (via our
IBuffer abstraction) and emit the
mask character (*).

The input handling code is rather uninteresting in long
form, but here's a snippet to give you a general idea (the
remainder is available in the full source code, attached):

I tried to emulate the basic behavior of the standard
ReadLine method as much as possible --
that said, I'm sure I missed a few shortcuts which I don't happen
to be aware of. If I missed something obvious, feel free to add a
comment and I'll update the source.

Using MaskedInputReader

Using the MaskedInputReader is very
simple. Here's a sample invocation which reads a
SecureString (from
Test.cs):

One of the primary motivations for building this library was
to enable accepting credentials from MSBuild tasks. This is likely
to be an increasingly common need with the release of Vista
inspiring more developers to run LUA. A task to install an
assembly to the GAC, for example, would require elevation if run
by a LUA user.

Summary

The feature set is summarized below:

Support for multiple string types.

Backspace and delete handling.

Line buffer navigation via arrow keys or Home / End.

The source code is attached to this post. It's MIT licensed,
which means it can be used commercially provided the copyright
stays in tact.