Well, VS.net 2010 has been released for at least two weeks now and you're probably thinking, "So what?! My VS 2008 works just fine, why should I run out and upgrade just because Microsoft decided to release something?"
While working as an employee for large enterprises I felt EXACTLY the same way, as well I should have. Late adoption makes sense in the enterprise because stability is key. The focus of the organization is very likely not software innovation; it's making a profit through the business core competency. Discarding a functional IT configuration in favor of the freshest available must be justified due to the cost of new licensing, user training and the explicit and latent costs of change.
Now as a principal in a small software development company the proposition is completely different. Being a late adopter would mean that I don't care about being capable of delivering the best possible solution to my consulting clients. Learning and using the best bits of the newest stack also make sense when considered from the software product development company perspective.
Building a product to successfully compete in the cutthroat software product marketplace requires not only an agile, creative, talented, hard working team but also a technical edge. The bottom line is that the cost of waiting is greater than the cost of adoption in our case.
Enough babble... time to drive you enterprise developers into a desire to learn the new bits in your free time and to whet the appetite of those of you who should be using this already. Here are my favorite highlights of .NET 4.0 and compelling reasons to start using the new framework now.
- ASP.net MVC 2.0 has been around for a while now and can't really be considered a new feature but it has finally shipped as an activated feature with the release of Visual Studio 2010.
MVC deserves a series of blog entries all its own to cover just the basics and I can't possibly do it justice with an example of reasonable size here. Instead, let me leave you with this thought regarding what you will find if you drink the kool-aid. If you are a developer who likes to know what HTML, JavaScript and CSS your client browsers are actually seeing when they load your app and you sometimes worry about layers upon layers of generated code between you and the processor you will find MVC a breath of fresh air. Put simply, it's smart, minimalist and extensible.
Here are some good resources to get up to speed if you'd like to say goodbye to the if (!Page.IsPostBack) nonsense : - The official ASP.net site has lots of good content
- Scott Guthrie's has a few thorough blog entries walking through the basics
- He's also the author of the comprehensive Nerd Dinner sample MVC app - an ebook published as a PDF. This is an excellent place to start.
- The MSDN overview is worth a look
- The code climber has a good overview of commonly customized/overridden segments of the MVC stack
- Dynamic language elements are not something I've personally found a need for yet, probably because I've been using a static language for too long. Regardless, it will be changing the C# landscape dramatically once this catches on. At it's core think VB6 Late Binding reincarnate; type-related checking by the compiler is turned off for the dynamic type. The interesting ramifications come with what you can do without the compiler slapping your hand:
- Many talk of developing meta-languages (Domain-Specific Languages or DSLs) but I have to wonder if there's return on investment down that road? Be the judge of DSLs for yourself. There's nothing like a good hands-on example to try a concept on for size.
Even if you don't delve into creating your own language it may still make sense to make segments of your codebase string-based and modifiable without recompilation. IronPython and IronRuby will allow you to do just that and to pass data between C# and your string-based code. - Expando objects are objects that can have their definitions altered at runtime. Imagine being able to write the code you're running with the currently running code. Yes, ouroboros does spring to mind, but there are some interesting applications of this feature. Python and Ruby need no longer be the envy of C#, at least not for being dynamic at runtime : ) Check out the Microsoft docs for the basics.
The new Dynamic Language Runtime (DLR) docs from Microsoft and the docs regarding the new dynamic type are both good and concise. They even have a good walkthrough of an example of how you might use dynamic. - SQL Server Reporting Services has FINALLY released an update to their deployable runtime. No more need to rely on the reporting services binaries that shipped with VS.net 2005 when doing local report rendering! Time to upgrade those SSRS deployment packages.
- System.Threading.Tasks is reason enough to start using .net 4.0 now if you are developing with multiple threads. Justin Etheridge has a good, brief overview on his blog. Here's a simple usage example where multiple threads make perfect sense and can easily be implemented using the new Task object. The ease with which we can now spawn asynchronous threads with StartNew and then join them back with WaitAll is a pleasure. There are many options and use cases to explore to fit your problem at hand. This is a simple starting point.
using System.Threading;
using System.Threading.Tasks;
...
public void Sync(IRequestKey key) {
HashDTO[] remoteHashes = null;
HashDTO[] localHashes = null;
Task t1 = Task.Factory.StartNew(() => {
remoteHashes = getRemoteHashes(key.Id);
});
Task t2 = Task.Factory.StartNew(() => {
localHashes = getLocalHashes(key.Id);
});
Task.WaitAll(t1, t2);
// compare and process local and remote data here
The Microsoft docs on the bigger picture of the concurrent processing plan and their docs on Tasks are worth a look. The usefulness of the static Parallel class will probably lead to its becoming commonplace in short order.
- Optional and named method arguments seems like a "me too" feature but not so much after you stop to think about it. Overloading is a great feature of object oriented programming, but what's even better is not having to write the overload at all. Optional method parameters do for methods what property initializers did for constructors in .net 3.5. Take this very simple, contrived example:
// the best we can do with C# 3.5
public List<dataitem> SimpleFind(string nameCriteria) {
// logic goes here, specific to just the name
}
public List<dataitem> SimpleFind(string nameCriteria, int? ageCriteria) {
// logic goes here for both name and age
}
// what we can do now with 4.0
public List<dataitem> SimpleFind(string nameCriteria = "", int? ageCriteria = null) {
// logic inspecting parameters passed goes here
}
The optional parameters are identified simply by having a default value specified with the = sign. It's not a revelation but writing less code to do the same job is always a welcome change of events to me. Of course, you could have always passed a null or default value to a method similar to the second in the sequence but SimpleFind("", null) just doesn't compare to SimpleFind() for readability.
Named parameters are used on the other side of a method call to specify the parameters being passed. It's obviously superfluous under normal operations but this comes in handy when passing only a couple of optional parameters to a method that has several to choose from, as in the below. As you can see all you need to do is prefix your parameter value with the parameter name and a colon.
- ClientIDMode is an overdue feature for ASP.net webforms. How many times have you found yourself needing to muck up your otherwise elegant Javascript with something nasty like the below simply because ASP.net webforms insists on mangling control names when it renders HTML?
function SomeInterestingJsFunction() {
var controlRef = $('#<%=txt.ClientID%>');
// this is where you interact with your asp.net generated control in js
...
}
The good news is that now you can choose to specify how ASP.net webforms generates its ID tags. We now have static, predictable, autoid and inherit. AutoID is the default and tells ASP.net to generate IDs the same as it's always been, the rest are all new. The most interesting (in my opinion) is static as it allows us to tell ASP.net to make the names we give our controls their HTML IDs. Check the MSDN overview for more details or a related MSDN article about accessing ASP.net controls from js.
- Tuples are a brand new feature that at first glance seems like maybe a bad idea. One definition of a tuple is an anonymous, immutable record type that you can pass between methods. Yeah, it does sound messy, doesn't it? On the one hand how much trouble is it really just to create a class with a few named properties rather than passing a tuple, but on the other hand if you consider how many data passing classes you normally create in a solution and then realize that coding most of them are now completely unnecessary...
public List<Tuple<DateTime, decimal, char, int>> GetRecords() {
Random rnd = new Random();
var result = new List<Tuple<DateTime, decimal, char, int>>();
for (int i = 1; i <= 100; i++)
result.Add(
// the static Create method uses type inference to create an anonymous type with strongly typed fields
Tuple.Create(new DateTime(2010, rnd.Next(1,13), rnd.Next(1,29)),
(decimal)rnd.Next(50, 500),
(char)rnd.Next(65,91),
rnd.Next(1,101)));
return result;
}
Apart from the potential reduction in the number of dto classes you need to code by hand, tuples also make functional currying techniques slightly more accessible from C#. Currying a function enables you to do partial application of a that function by passing fewer arguments than it originally expected. The result of the incomplete call is a state in which the remaining evaluation is "waiting" for additional arguments to be provided.
What's that? You're saying "Why would we entertain this craziness and how does it relate to the code I need to write?" Two benefits that I can see are promoting broader function reuse and the methodology of solving complex problems through iterative functional complexity. Passing a simple function to a simple function to a simple function allows for reuse of 3 functions as opposed to the single function resulting from the creation of a single context-specific function that expects all required arguments.
Now you're probably wondering how this relates to tuples... Tuples allow you to easily pass more complex data between your curried functions to solve real world problems. Matthew Cochran has a good example of what currying looks like in C# and this post does a good job of explaining things from the ground up. WARNING - this last reference is in F#, speaking of which...
- F# is Microsoft's showcase functional language and while it's been out there for a few years it is now finally a first class citizen with the VS.net 2010 release. Lambdas and property initializers are elements of functional programming creeping into C# - so when programming functionally why not go full bore and use an F# project? It will warp your mind a bit (it does mine), but it's probably time we all add F# to our coding arsenals. Start here and the language reference is a good next stop. I am definitely a newbie on this front. I think of F# like the medicine I should be taking but don't have time to go to the pharmacy to get a refill. Like anything else the use it or lose it rule applies...
- The last feature (and deservedly least in this list) is the inclusion of a chart control for ASP.net webforms. While the Microsoft chart control was available for download under 3.5 it's now "in the box". The Microsoft docs leave something to be desired but the 4guysfromrolla site has a good article on the ins and outs. If you'd rather just see a snippet to get the gist here you go; with a tuple to make it interesting. Databinding is no problem as you can see. For complete flexibility there is also a Points collection that can be specified. The plethora of chart types implemented makes this addition to the toolkit pretty valuable.
// the control definition in the aspx...
<asp:Chart ID="Chart1" runat="server" Width="658px">
<series>
<asp:Series ChartType="Line" Name="Series1">
</asp:Series>
</series>
<chartareas>
<asp:ChartArea Name="ChartArea1">
</asp:ChartArea>
</chartareas>
</asp:Chart>
// and the codebehind to bind a simple tuple; Item1, Item2 ... ItemN is what you use to reference your tuple fields by name
Random rnd = new Random();
var records = new List<Tuple><DateTime , decimal>>();
for (int i = 1; i <= 12; i++)
records.Add(
Tuple.Create(new DateTime(2010, i, 1), (decimal)rnd.Next(50, 500)));
Chart1.Series["Series1"].XValueMember = "Item1"; // the field to provide the x coordinates for each plotted value
Chart1.Series["Series1"].YValueMembers = "Item2"; // the field(s) to provide the y coordinates for each plotted value
Chart1.DataSource = records;
Chart1.DataBind();
There are quite a few things that I'm not mentioning as things that I personally care about but are, to be fair, things that you may find invaluable. Here are a few:
- While we'll inevitably have to use Entity Framework "4" (since we consult) we use NHibernate as our ORM whenever we have a choice. Here are a couple of links on EF. (The quotes around 4 are intentional; the current release is masquerading as 2 versions later in maturity!)
- WCF, WPF and WF all have improvements to boast. There's even a Microsoft REST offering coming along. We use Mindtouch Dream, an open source alternative, instead for webservice communications and don't do a whole lot of fat client development anymore so these incremental improvements are not of immense interest to us.
- Visual Studio.net 2010 debugging now supports multithreading. (Pardon my ire on the tardiness of this offering as I could have used this in VS 6.0 12 years ago while fighting for hours with the Windows API during subclassing of the listview control?)
My only disappointment is in seeing Microsoft fall a bit behind in their cloud tool offerings. They are talking the talk and Azure is well-conceived but the AppFabric won't be ready for another 3 months. Until the tools are completely there and entrenched developers are not going to build in the cloud and business leaders will not join the party, at least not the party held by Redmond. Jeff Bezos is still playing pied piper visionary very successfully. Amazon continues to do nearly everything right and Rackspace's offerings are maturing very quickly. As a developer who writes the majority of his code in a Microsoft language I'm hoping for more substance soon.
Tags: