Locations of visitors to this page

    Blog List       Minimize  
,NET:ASP:MVP
.NET
.NET 3.5
.NET:ACL
.NET:AppDomains
.NET:ASP
.NET:ASP ServerControls
.NET:ASP:Commerce
.NET:ASP:Config
.NET:ASP:JSON
.NET:ASP:Layout
.NET:ASP:Media/Flash
.NET:ASP:Mobile
.NET:ASP:Monitoring
.NET:ASP:MVC
.NET:ASP:Navigation
.NET:ASP:Stress Testing
.NET:ASP:Validation
.NET:ASP:WebParts
.NET:C#-Trig
.NET:CAB
.NET:CAS
.NET:Certification
.NET:CF
.NET:Collections
.NET:Configuration
.NET:Cryptography
.NET:Db
.NET:Delegates
.NET:Deployment
.NET:Diagnostics
.NET:Documentation
.NET:Encoding
.NET:Environment
.NET:Extension Methods
.NET:Globalization
.NET:I/O Streams
.NET:Interop
.NET:IO:Mail
.NET:IsolatedStorage
.NET:LicenseManager
.NET:LINQ
.NET:Metrics/Quality
.NET:Mono
.NET:MSOffice
.NET:Optimization
.NET:Patterns/Practices
.NET:Phone7
.NET:Reflection
.NET:Remoting
.NET:Reverse Engineering
.NET:Serialization
.NET:Silverlight
.NET:Silverlight UserGroup
.NET:Silverlight:Phone7
.NET:Threading
.NET:WCF
.NET:Windows Services
.NET:WinForms
.NET:WPF
.NET:Xml
Admin
Admin:Creating Software
Admin:CruiseControl
Admin:Estimating
Admin:Installers/Packaging
Admin:Methodologies
Admin:PM
Admin:SourceControl
Admin:UnitTesting
Admin:VisualStudio
Arch:Gen
Arch:Patterns
Arch:UML
Blogging
DB:Sqlite
DB:SqlServer
DB:SqlServer CE
DB:VistaDB
Graphs
IT
IT:DNN
IT:DOS
IT:IIS
IT:MailServers
IT:MS Office
IT:OS (XP/Vista/7)
Misc
Misc:Hardware
Misc:Humour
mISV:Accounting
mISV:Marketing
OS:Vista
Personal
Personal:Children
Personal:Faith
Personal:Family
Personal:History
Personal:Politics
Places:New Zealand
Places:Paris
Presentations
Tech:CSS
Tech:Regex
Tech:SQL
Tech:Web:HTML
Tech:XML/XSL
Web:HTML5

             
    Sprouting Synapses       Minimize  

             
Explorations of new features and syntax additions brought in with .NET 3.5.

Tip:
After you've got a good grip on how these new language features work, you should move on to exploring LINQ, which I post about separatly, in the LINQ Blog Category...

Over the past few weeks I've been blogging on on all the various additions to C# that came in with C# 30.0 in the .NET 3.5 Framework that became commonly available with Visual Studio 2008.

I've covered all the bits and bobs needed to make LINQ a possibility, while avoiding discussing LINQ itself.

That's because I couldn't do a better job introducing how LINQ takes advantage of Extension Methods, Anonymous Types, Object Initializers, and ultimately Lambda Expressions than the following article by Anson Horton.

It was written quite a while ago -- but I don't think I've read a more succinct introduction since.

 

Links:

The Evolution Of LINQ And Its Impact On The Design Of C#

In an article on codeproject.com I found:

When comparing performance of these two approaches, I conclude that the actual time to dynamically build and compile a single dynamic comparison method is much less when using Emit, by almost a factor of 10, compared to using Expressions.

Actually, the whole section that was of interest to me was:

Expression versus Emit

Before .NET 3.5, the only way to create code on the fly was to use the classes in the System.Reflection.Emit namespace, which requires low-level knowledge about the low-level MSIL instructions. Ref [4] uses this method to create much optimized sort comparison routines dynamically. In the Dynamite library, I included my own version of this approach in the method ComparerBuilder<T>.CreatePropertyComparisonThroughEmit. Here is a snippet of the code from this method, that creates a comparison for string typed properties:

...
DynamicMethod dynMethod = new DynamicMethod("Compare" + propName, typeof(int),
                                            new Type[] { t, t }, t);
ILGenerator ilgen = dynMethod.GetILGenerator();

if (propertyType == typeof(String))
{
    // Call String.Compare(s1,s2,StringComparison.CurrentCultureIgnoreCase)
    ilgen.Emit(OpCodes.Ldarg_0);
    ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null);
    ilgen.Emit(OpCodes.Ldarg_1);
    ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null);
    ilgen.Emit(OpCodes.Ldc_I4_1); // 1 = CurrentCultureIgnoreCase
    ilgen.EmitCall(OpCodes.Call, stringCompareMethod, null);
    if (ascending == false)
    {
        ilgen.Emit(OpCodes.Neg);
    }
    ilgen.Emit(OpCodes.Ret);
}
...
return (Comparison<T>)dynMethod.CreateDelegate(typeof(Comparison<T>));

When comparing performance of these two approaches, I conclude that the actual time to dynamically build and compile a single dynamic comparison method is much less when using Emit, by almost a factor of 10, compared to using Expressions. Using Expressions, on the other hand, is much easier and safer. In addition, thanks to caching, the extended compile time will normally not be an issue. Furthermore, when comparing total sorting times of large lists, I normally did not see any significant improvements by using Emit. If absolute top performance is required, however, Emit might in some cases be used to create highly optimized multi-field comparison routines that is even faster than C# compiler-generated code (see the DynamicComparer in ref [4], but remember that DynamicComparer does not support nested properties).

What you can do with Expressions is also much more limited than what you can do with Emit. As Expressions only support lambda expressions, you cannot use local variables and assignments. In the Dynamite library, I circumvented these limitations by using invocations of subfunctions with arguments to store intermediate results.

 

Links:

http://www.codeproject.com/KB/linq/dynamite_dynamic_sorting.aspx?display=Print

lamdba expressions are a very succinct way of defining anonymous methods (ie: delegates) with type inference thrown in the mix.

A C# lambda expression consists of two aspects, separated by the lambda operator (=>).
•        To the left of the lambda operator is the set of arguments to process.
•        To the right of the lambda operator is the set of code statements which process the arguments in question.

private void Form1_Load(object sender, EventArgs e) {

  // .Net 1.1 named method and delegate instantiation 
  button1.Click += new EventHandler(button1_Click);

  // .Net 2.0 named method and delegate inference
  button1.Click += button1_Click;

  // .Net 2.0 anonymous method
  button1.Click += delegate(object s, EventArgs args) {
    Text = “Button Pressed”;
  };

  // .Net 3.0 Lambda Expression with type inference 
  button1.Click += (s, args) => Text = “Button Pressed”;
}


//For .NET 1.1 and 2.0:
void button1_Click(object sender, EventArgs e){
  Text = “Button Pressed”;
}

Src: the wonderfully clear snippet of code came from a post originally titled "Lambda expressions in 5 minutes"...

 

Another example, this time of a lambda expression which expands to be a Predicate<T> delegate:

List<int> myList = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
myList.RemoveAll(x => x > 5);
//myList now == {1,2,3,4,5}

Src: StackOverflow

 

 

 

 

BUT ...the part that is not often presented up front is:

"Slightly oversimplified: a lambda function is one that can be passed round to other functions and it's logic accessed.

In C# lambda syntax is often compiled to simple methods in the same way as anonymous delegates, but it can also be broken down and its logic read.

For instance (in C#3):

LinqToSqlContext.Where( row => row.FieldName > 15 );

LinqToSql can read that function (x > 15) and convert it to the actual SQL to execute using expression trees.

The statement above becomes:

select ... from [tablename] 
  where [FieldName] > 15      --this line was 'read' from the lambda function

This is different from normal methods or anonymous delegates (which are just compiler magic really) because they cannot be read.

Not all methods in C# that use lambda syntax can be compiled to expression trees (i.e. actual lambda functions). For instance:

LinqToSqlContext.Where(     
  row => SomeComplexCheck( row.FieldName ) );

Now the expression tree cannot be read - SomeComplexCheck cannot be broken down.

The SQL statement will execute without the where, and every row in the data will be put through SomeComplexCheck.

Lambda functions should not be confused with anonymous methods.

For instance:

LinqToSqlContext.Where(     
   delegate ( DataRow row ) {         
     return row.FieldName > 15;     
   } 
);

This also has an 'inline' function, but this time it's just compiler magic - the C# compiler will split this out to a new instance method with an autogenerated name.

Anonymous methods can't be read, and so the logic can't be translated out as it can for lambda functions."

Src: http://stackoverflow.com/questions/16501/what-is-a-lambda-function

For the last couple of posts I've been hammering away at the concept that you don't have to automatically limit your assemblies to compile against .NET 3.5 just to start using some of the new features that shipped with .NET 3.5.

The bare facts are that a lot of the new features are not Framework Features -- but actually Compiler tricks, and therefore are immediately available to you -- as long as you are compiling using the compilers that shipped with .NET 3.5 (ie: you're using VS 2008).

 

You can use all of the following now:

What is not available to .NET 2.0, because it relies on classes defined in .NET 3.5 assemblies -- is LINQ.

 

Except there is this route to consider:

http://rogeralsing.com/2008/03/31/linq-to-objects-for-net-2-available/

Lambda expressions have been around a long time before they became known to .NET users:

In mathematical logic and computer science, lambda calculus, also written as λ-calculus, is a formal system designed to investigate function definition, function application and recursion.
It was introduced ...in the 1930s...and forms the basis of a paradigm of computer programming called functional programming.

The lambda calculus can be thought of as an idealized, minimalistic programming language.

It is capable of expressing any algorithm, and it is this fact that makes the model of functional programming an important one.

Functional programs are stateless and deal exclusively with functions that accept and return data (including other functions), but they produce no side effects in 'state' and thus make no alterations to incoming data.

Modern functional languages, building on the lambda calculus, include Erlang, Haskell, Lisp, ML, and Scheme, as well as more recent languages like Clojure, F#, Nemerle, and Scala.

Src: From Wikipedia, the free encyclopedia

You'll notice from the comments on this post that ...it didn't go exactly as the poster wanted. People are pissed with the direction MS is taking:

http://blogs.msdn.com/adonet/archive/2008/10/31/clarifying-the-message-on-l2s-futures.aspx

 

Later Damien Guard responded...ending up with:

"...

In conclusion

DON’T PANIC
(in large, friendly letters)

LINQ to SQL will continue to work and EF will better address the needs of LINQ to SQL users with each new release.

[)amien"

 

Hum. Ok. I'll wait and see...but it better end up being a great replacement...

 

 

Links:

http://blogs.msdn.com/adonet/archive/2008/10/31/clarifying-the-message-on-l2s-futures.aspx

http://stackoverflow.com/questions/252683/is-linq-to-sql-doa

http://ayende.com/Blog/archive/2008/10/31/microsoft-kills-linq-to-sql.aspx

http://damieng.com/blog/2008/10/31/linq-to-sql-next-steps

I'm usually read skim MSDN's documentation in a rush, get the job done, and later, when I have time to come back, am surprised at how much info was right there in front of my eyes, if I had only slowed down. (I know...I shouldn't admit these thing).

In terms of Anonymous Types just about all that one needs to remember is right there, in the first paragraphs:

    • Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object [of class type] without having to first explicitly define a type.
    • The type name is generated by the compiler and is not available at the source code level.
    • An anonymous type is limited to method scope.
    • An anonymous type [...is directly derived from object].
    • The type of the properties is inferred by the compiler [ie, no way to specify Type].
    • No other kinds of class members such as methods or events are allowed.
    • If you do not specify member names in the anonymous type, the compiler gives the anonymous type members the same name as the property being used to initialize them.
    • You must provide a name to a property that is being initialized with an expression.

Read More »

The C# Version 3.0 Specification of the .NET Framework introduced the var keyword...which is syntactic sugar -- but I still can't figure why that's good in this case...

Read More »

The C# Version 3.0 Specification of .NET introduced a nice succinct way of instantiating and initializing instances and collections all in one statement, called Automatic Initialization.

Read More »

 

The C# Version 3.0 Specification of the .NET Framework introduced Extension Methods, which are a neat way of injecting methods into a class defined by someone else. 

What I mean by that is that if, for example, you've enjoyed that the string class has a ToUpperCase() method and a ToLowerCase() method -- but sort of felt that the string class was missing a ToPrettyCase() method, you can now very easily add it.

Read More »

The C# Version 3.0 Specification of the .NET Framework introduced some syntactic sugar that allows you to define properties in a much more succinct way.

 

 

Read More »

Copyright 2007 by Sky Sigal