Re: Some notes on C# 3.0 (was RE: [DOTNET-CX] How to overload == for System.Double)

"Bart De Smet [MVP]" <[email protected]> Tue, 6 Feb 2007 00:30:34 +0100
Newsgroups gmane.comp.windows.devel.dotnet.cx
Message-ID <006401c7497d$a2a59a10$e7f0ce30$@net>
Sure here we go. This is what the compiler does consecutively:

> IEnumerable<string> selectedWords =
>  from p in EinsteinQuote
>  where p.Equals("any") != true
>  select p;

becomes (using lambda expressions)

> IEnumerable<string> selectedWords =
>  EinsteinQuote.Where(p => p.Equals("any") != true).Select(p=>p);

becomes (using name resolution that will find extension methods to be in
scope in order to resolve Where and Select):

> IEnumerable<string> t1 = IEnumerable<string>.Where(EinsteinQuote, p =>
p.Equals("any") != true);
> IEnumerable<string> selectedWords = IEnumerable<string>.Select(p=>p);

becomes (using lambda-to-delegate+anonymous_method translation):

> IEnumerable<string> t1 = IEnumerable<string>.Where(EinsteinQuote,
UnspeakableMethod1);
> IEnumerable<string> selectedWords =
IEnumerable<string>.Select(UnspeakableMethod2);

with

private bool UnspeakableMethod1(string s)
{
   return p.Equals("any") != true;
}

private string UnspeakableMethod2(string s)
{
   return s;
}

Note: the select p stuff isn't necessary in case there's no real projection
(optimization). In case you do some projection like select new { Result =
p.ToUpper(), SomeNumber = 123 }, the UnspeakableMethod2 will be required and
will perform quite some work (i.e. creating an instance of an anonymous type
that has a Result and SomeNumber property/field and settings these values).

Notice that all of this allows you to chain stuff much like you can do with
string's:

string s = "Bart";
string r = s.ToUpper().Trim().PadLeft('*', 9).Substring(1,5).AndSoOn...;

Thanks to the "Standard Query Operators" of LINQ one can do the same with
IEnumerable<T>. Extension methods are required to allow this convenience.
For sake of the demo, consider the following string extension:

public static class MyExtensions
{
   public static string Reverse(this string s) //this keyword used to
indicate an extension method for type "string"
   {
      char[] c = s.ToCharArray();
      Array.Reverse(c);
      return new string(c);
   }
}

Which allows you to write something like this:

string r = s.ToUpper().Reverse().Trim().PadLeft('*', 9).Substring(1,5);

whereas in the past you'd have to write:

string t = s.ToUpper();
string r = MyExtensions.Reverse(t).Trim().PadLeft('*', 9).Substring(1,5);

effectively breaking the convenient call chain.

If you're interested in how the Standard Query Operators work take a look at
my CodePlex project on www.codeplex.com/LINQSQO. Enjoy!

-Bart

-----Original Message-----
From: Discussion relating to the specifics of the C# and Managed C++
languages [mailto:[email protected]] On Behalf Of Alan Baljeu
Sent: maandag 5 februari 2007 15:26
To: [email protected]
Subject: Re: [DOTNET-CX] Some notes on C# 3.0 (was RE: [DOTNET-CX] How to
overload == for System.Double)

> I guess it all depends on personal taste; for some
> individuals things like lock, using and foreach in C# 1.0
> could be seen as syntactical sugar for library functionality;
> in C# 2.0 the stuff around iterators is a far more complex
> piece of syntactical sugar that performs much more code
> generation than some might think (one keyword "yield" results
> in a massive amount of code generation); in C# 3.0 the
> expression tree stuff is on that same level while other
> features are much simpler substitution patterns with a
> few[C#]:few[MSIL] mapping scheme. You might argue that the
> way of thinking might be decisive to classify stuff in the
> syntactical sugar camp or not; whether you think
> implementation-driven (implicitly mapping on the runtime,
> MSIL, stack-based evaluation, processor instruction
> generating statement sequences, whatever is in a name) or
> results-driven (which LINQ syntax is clearly a good example of).

You mentioned a variety of things which seemed good and natural to C#,
including all kinds
of sugar and extension methods.  I understand C# is happy with a variety of
keywords which
introduce some new context for the code which follows.  I also understand
that these are
usually shortcuts for something which could be written more verbosely.


So I can understand these new keywords, can you de-sugar for me the from,
where and select
keywords below, and just use de-keyworded C# 3.0?

> IEnumerable<string> selectedWords =
>  from p in EinsteinQuote
>  where p.Equals("any") != true
>  select p;

Given that, I think I would understand more of what's going on.

===================================
This list is hosted by DevelopMentor.  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com