Showing posts with label Orcas. Show all posts
Showing posts with label Orcas. Show all posts

Sunday, October 28, 2007

.NET 3.5: The Good Stuff

With my last two postings "Partial Methods. What The?" and "C# 3.0 Extension Methods? A Good Idea?" taking shots at new features in .NET 3.5, I wanted to make a new post where I look at some of the new features I'm actually excited about. Even though this blog is titled "Chapman's Constant Complaining", I'm not negative about everything! There is a lot of good on the horizon.

1. Anonymous Types



Anonymous types are tool in .NET 3.5 that allows you to specify types based on the properties contained in the type, rather than the class declaration. The type has no name, meaning that you will not be able to construct a new instance of this type by using the new className() mechanism.

Basically, anonymous types free the developer from having to define a new class for every one off purpose in the application. I'm an NHibernate addict. I think it's absolute fabulous tool, and if you're reading this and you've never tried it, go download it right now. You can find it at www.nhibernate.org. Anyway, with NHibernate I find myself creating classes all the time which contain just the data I want returned from a query. You then create a constructor which takes just the fields you want and then reference this type in your HQL query. This is very helpful when trying to tune an HQL query for a complex search page where you need to collect display data from many objects, or even aggregates of child data.

In theory anonymous types will free developers from this time consuming task. NHibernate, much like LINQ, would be able to construct a new anonymous type for us containing just the properties we asked the HQL to return us. Note that this is actually the main use of anonymous types in .NET 3.5, support for arbitrary data being returned from LINQ expressions.

Anonymous types go beyond just queries though. How many times have you needed a simple two or three property class to perform calculations within a method? I've created one off "info" classes in the past. I don't know why I call them info, I just do. We now have the ability to define that "info" class as an anonymous type and no longer worry about the actual class declaration.

2. LINQ (Language Integrated Query)



This is the big daddy of .NET 3.5. Who hasn't heard of LINQ? The way it has been talked about it sounds like it will solve every problem ever created by a developer. I actually think LINQ is way over hyped. over hyped or not, it's still a very cool new feature which will change how we develop applications with .NET going forward.

First, I want to cover why I think LINQ is over hyped. LINQ is being talked about like there has never been anything similar in the past. Most examples which are provided are used to query a database using LINQ to SQL which is really just a very simplified OR/M tool. What some people don't realize is that tools like NHibernate, LLBLGen Pro, Entity Spaces and others have been around for a long time, offering better OR/M tools and very sophisticated query mechanisms for some time.

Now, LINQ still deserves it's credit here because it actually takes what we've learned from our OR/M tools a bit further. I'm most exited about having strong typing on my queries written in C#. I hate that the only tools I have available to me are based on strings. If an object's property is renamed it is often very difficult to spot any potential queries which were not updated until runtime. Having this check performed at compile time is a huge advantage.

Secondly I think it helps people look at their C# objects in a different manner. When trying to explain OR/M tools to developers who haven't previously used an OR/M I try to explain that the OR/M is really a synchronization tool, not a database persistence tool. Think of the database as just your extended memory, perhaps a second level memory store. As far as you are concerned there is no difference between objects in memory and objects in a database. LINQ helps to re-enforce this thinking in that you can write the same queries against your objects in memory as you do your objects in the database. I think this may cause some issues for some people at first, but eventually will be very beneficial.

3. Object Initializers



This is sort of a minor one. Object Initializers seem like they are purely syntactic sugar which can be skipped, but they allow us to offer new features like the above mentioned anonymous types and LINQ. Object initializers also allow us to offer mechanisms to define our objects without having to worry about which constructors the class's author defined for us. I think overall it makes the code a bit cleaner and easier to read.

4. Type Inference (The C# var keyword)



This could be argued as a minor point as well, except for the necessity of the feature for the above mentioned anonymous types and LINQ. I think it is convenient to be able to declare types with a var keyword when declaring a variable with an assignment.

That being said, it is a feature I don't see myself using a whole lot. I would prefer to type the entire type when it is known. This makes it a bit easier to read the code in my opinion. If you are using an IDE like Visual Studio 2008 it should not make much of a difference, but is it really that hard to write int i = 1 instead of var i = 1? I know we're really concerned about the long generic types, but a little extra typing never hurt anyone.

So while I think this is a very useful feature, I'm a little concerned that it may be taken to the extreme in some code where every variable declaration is defined as var. Plus people already make the mistake of constructing new types only to throw them away on the next line. I hope this doesn't make that problem worse. Who hasn't seen the following code?


ArrayList list = new ArrayList();
list = RunQuery();


5. Lots of Other Stuff



There are actually many other cool features built in to .NET 3.5 for us, like built in APIs for RSS 2.0 and ATOM as well as an improved garbage collector. Overall I'm excited about .NET 3.5. Now if only we could do something about those extension methods and partial methods!

--John Chapman

Partial Methods. What The?

I alluded to this topic yesterday with my post "C# 3.0 Extension Methods? A Good Idea?". Today I want to discuss Partial Methods, another new feature of .NET 3.5. If you are unfamiliar with Partial methods, you can get a briefing here.

I think Microsoft has really gotten off track with this enhancement. The possible advantages seem so insignificant that I can't imagine why this was worth anyone's time. This is my #1 most loathed feature in all of .NET. The only feature I've seen talked about is a mechanism for lightweight event handling, or should I say pseudo-event handling?

We already have mechanisms for listening to events in .NET. If we want to perform operations in a BeforeUpdate() and AfterUpdate() manner we could listen to events which would fire named BeforeUpdate and AfterUpdate.

I understand the idea behind the "conditional method" aspect of the feature. But does it really kill us that much to use an if statement? Does one if statement which checks to see if any listeners are registered for an event kill the performance of the system? If this is your system, then I'm jealous. To get to the point where every if statement needs to be taken into consideration due to performance constraints seems like an intriguing problem, which many of us would love to work on. It just seems like there aren't many examples of this in the real world. We are ok with the statement which checks for event listeners. At least now our code is readable and we don't have to worry about not knowing what our code will output by just looking at our method's code.

This whole approach makes me think of JavaScript and the mechanism used for it's pseudo-event handling. It seems that with JavaScript we have taken the exact opposite approach to what we are seeing with partial methods. In JavaScript we used to rely (or maybe people still do) on a mechanism which is very similar to partial methods.

Haven't we all seen this:


<input id="btn" type="button" onclick="alert('button clicked');" />


or alternatively this:

document.getElementById('btn').onclick = function(e) { alert('button clicked'); };


The way this works is we assign a function to the already predefined declaration. Then the button object will call the defined method when the user clicks on the button. This is very similar to how partial methods are intended to be used. The developer (or code generator) will create a definition for the method. If you want some code of your own to run when an event takes place you simply provide the implementation of the previously defined method. There you have it, simple events in an old school JavaScript way.

But what have we learned with JavaScript? This isn't the best way to use events. What happens when we want to have multiple listeners? Using the above code whichever listener registers their method last will win, all earlier listeners will be discarded. We've been introduced to a new mechanism in JavaScript. For brevity I'll only cover the ASP.NET AJAX 1.0 approach. ASP.NET AJAX brought us the $addhandler() method which registers events on objects much like we are used to in .NET. Now we are able to have as many listeners as we want. We no longer worry about destroying prior listeners.

So if we have made these strides to move away from the "partial methods" type approach in JavaScript why is our new .NET library moving backwards? I really hope I never have to deal with partial methods in the code I work with.

What scares me most about partial methods is what happens when they get into the wrong hands. The potential for writing unreadable/unreliable code is astronomical. Lets all hope we are spared these experiences.

Am I off base here? What am I missing?

--John Chapman

Saturday, October 27, 2007

C# 3.0 Extension Methods? A Good Idea?

While I was attending the Day of .NET conference in Ann Arbor, MI last Saturday (10/20/2007) I had the opportunity to talk to an old co-worker of mine. He said something that really caught me off guard. While talking about new things that had us excited, he told me he was really excited about extensions methods and said they were really going to help him where he works. If you are new to extensions methods take a look at an old blog post by Scott Guthrie here.

I don't want this to sound like I am saying anything bad about this former colleague of mine. He's a very sharp person and an excellent developer. I'm confident that he will use this technology appropriately, but at the same time there are other options, and the statement just caught me way off guard.

Of all the new things to get excited about, extensions methods would have been near the bottom of my list. In fact the only reason they aren't at the absolute bottom is because of the wonderful new feature known as partial methods (More on that another day).

Honestly, extension methods scare me half to death. The existence of extension methods and the previously mentioned partial methods scare me so bad I could see myself recommending holding off on .NET 3.5/C# 3.0 until a proper policing process is put in place.

In a quote on the Scott Guthrie blog, Scott made a true enough statement which said "When used correctly, I think you'll find that Extension Methods can significantly improve code comprehension within code reviews, and lead to fewer lines of code and fewer bugs." Now, that is fine and all, but I'm not worried about when they are used correctly, I'm worried about when every unqualified programmer gets his or her hands on this dangerous new technology. OK, so Microsoft needed extension methods to implement LINQ, I understand that, but couldn't we have maybe hidden it from other developers? Maybe we could have found another way?

If you are wondering why I'm so paranoid about this, it is because of the massive amounts of incomprehensible code I've seen in my life. I just see this adding to it. People who do not understand the purpose of extension methods, or have the judgment to properly determine when they should use them and when they should not use them are going to litter in our code.

In most applications I have worked on the String class plays a monumental role in our development effort. I can see it now where a developer gets it in his or her head that we need mountains of extension methods written on the string class. Now you may say to me, "You'll only see them if you include that namespace though". Well, I can see these same developers saying "It's such a pain to have to keep adding a using statement to my code files when I want these awesome string extension methods everywhere! I'll just put in the the System namespace, then it'll always appear for me! Just imagine code where you could use a string for anything. Every conversion method imaginable can live on the string. The string class will have the ToInt32() method, the ToInt64() method, the ToDecimal() method, then it will get even more fun when we start seeing things like ToOrder() where the extension method will convert the string to an Order number then load the Order object from the database and return it. The possibilities are limitless!

Let's not pretend like we haven't seen developers use the string object for way more than it is supposed to be used for. I've already had to put up with it used as a rounding mechanism, if we just take a decimal/double output it to a string with two decimal places, and then parse it with the decimal/double class we'll have a rounded number to two decimal places! What if I just want a DateTime object with the date value but a time of midnight? Since I don't know about the Date property of the DateTime I might as well use the ToShortDateString() method and then DateTime.Parse() to get the new DateTime value back without a time! What could be more awesome? Can't you see these same people using the new extension methods to shoot themselves in the foot?

We'll have code reviews only to find their code is near impossible to read. A senior developer may write a library to be used throughout the application to keep things consistent, scalable, reusable or otherwise in line with the goals of the company/team, only to find that another developer though it needed some new methods which completely violate the interface of the library. Now other developers start seeing these new methods in their intellisense thinking they are part of the library, only to later find out that any code written using these extension methods now needs to be re-written.

I've had developers change core libraries on me before where they had no business doing such. I previously built a system where every message returned from our business objects was associated with a code in an enumeration. This enumeration is then used to look up the appropriate message depending on the culture/language of the user (Even if the initial releases only had English) when displayed. Developers though this was "inconvenient" and too time consuming, so what did they do? They added a new message type where you just provide the string you want to display (in English) and a generic message code like "Error". Wow, now it is so much easier to write these business object methods!

Now this was easy enough to catch, and in all honesty probably an honest mistake where they didn't properly understand why we were doing what we were doing. I fear extension methods are just going to make things like this harder to catch!

Why do we need the extension methods when we can just use the static class utility methods instead? You want to have some one off method to check for the validity of a string as an e-mail address, but don't want to write an e-mail class? How about an EmailUtilitity static class with a static method IsValidEmailAddress(string email)? Now instead of writing


if (email.IsValidEmailAddress())

you instead write

if (EmailUtility.IsValidEmailAddress(email))

What is so horrible about that syntax? To me it is far easier to read, more maintainable and what most of us are already used to! Just about any use I can think of for an extension method can be written this way instead, and that's how I would prefer to see it.

Am I off base here? Is there some big picture I am missing? Let me know, I would love to know why extension methods are actually a feature we all need. It would surely make me feel a lot better about the prospect of upgrading to .NET 3.5. As it stands now I'll probably recommend upgrading to Visual Studio 2008 for the added JavaScript support, but using the .NET 2.0 libraries instead of the 3.5 libraries.

--John Chapman

Blogger Syntax Highliter