Franken# .Net

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Messages
2,097
Location
USA
After reading this thread and reading an article, frankly, I am starting to get quite frustrated with .Net. They created something powerful and flexible yet simple. The essence of elegance. Then they tack on generics, nullable types, and partial classes. Now we have extenders, lambda expressions, implicit types, object initializers, anonymous types... We are taking C#, throwing in everything bad about VB (don't get mad, VB users, you know it has potential for horrible programming practices), adding the confusion of C++ (don't get mad C++ users, you know that it takes a lot more time to learn and requires a much finer understanding of the language to fully utilize all its features, and I'm sure you remember the utter confusion the first time you looked at C++ code), and creating FrakenSharp .Net.

I don't understand extenders. Isn't the idea to inherit a class in order to extend it? And isn't the idea that a sealed class is specifically meant to not be extended? I can see where an extender can be useful, but it looks like we are losing touch with the OOP and managed code virtues that made .Net so great. What is so horrible about creating a function that acts on a specific class without adding the function to that class' interface? The extender-free code isn't really any more or less reuasble, is it? We loose the OOP syntax, but extenders aren't OOP in the classic sense, are they?

When you call a delegate pointed to a function of an interface implemented by a generic class implicitly typed by object initializers, just what the hell function are you calling? What about when you unwittingly call an extender function and can't find it in the definition of the class that you are calling it for, or any bases of that class. It is like giving a whole new meaning to spaghetti code. All over again we can't tell where program control is coming from or where it is going.
 
I can see Extenders being useful in a select number of scenarios (I can also see them being abused far more frequently) when a sealed class doesn't provide a piece of functionality that you use frequently. Also extenders do not have access to the class internals the same way a derived class would so the abstractions and decisions made by the original class are not being compromised.

e.g. Strings have ToUpper and ToLower methods but no ToTitleCase - even though the functionality is present (buried away somewhere in System.Globalisation), the ability to easily add a .ToTitleCase() to a string could be useful and the resultant code looks more OO even though it isn't because of the less explicit syntax in calling your static 'helper functions'.
e.g
C#:
string s = "Test string HeRE";
//with extenders
s = s.ToTitleCase();

//without
s =Utils.String.ToTitleCase(s);
Similar ideas could be used for things like normalising white space etc.
As the PDC docs themselves indicate though extenders are a tool for specific problems and should be used sparingly, like any other coding construct used correctly it can be a boon; used badly it does more harm than good (a bit like a power tool really ;)).

I can see some ease of use from the idea of object initialisers but nothing that gets me overly excited and not coming from a lisp / ruby background I'm not entirely sold on lambda expressions either.

Anonymous delegates can help to reduce the number of methods present in a class, especially when the callback etc. the delegate is being used for isn't overly complex, plus the ability to have local variables scoped to the anonymous delegate as well. Not sure about anonymous classes however...

Nullable types are again a tool for a specific purpose, when dealing with data access code they can drastically reduce the amount of code for handling null values and associated exceptions.

Generics however I do feel are a very worthwhile addition, the amount of code you no longer need to write when dealing with arrays / collections etc is a big time saver, also the lack of runtime errors that need handling, implicit or explicit casting no longer being needed etc all contribute to the quality of the code.
 
To extend PD's power-tool analogy, here is a true story:
When I was younger I didn't have a circular saw - I only had a jigsaw (a small hand-held power saw with a tall skinny blade, used mainly to cut small curves). I had to trim half of an inch off of a door to make it fit my irregular doorframe. I decided to use the jigsaw. You can probably imagine just how bad the door looked when I was done - like the side of a ridged potato chip. Did it work? Oh yeah, that door was no longer too wide. It wasn't straight and it wasn't pretty, but it worked and I was proud. It also took about 45 minutes to cute 2.5 feet and ruined the blade, but it worked.

Now that I'm older and more experienced, I would never in a million years try that again.

I can see people creating classes and then using extenders to fix them instead of adding the functionality they need. I can already hear the arguments as to why they SHOULD be extended but they will likely be excuses rather than valid reasons. Unfortunately for purists, who want everyone to do everything "right", there will always be the issue of balance. At some point you have to give people the tools and let them make mistakes and learn from them. Programmers generally fall into two categories: those that want to be programmers and those that just do it because it's their job. I want to be a programmer and I want to be good. For me, that also means investing the time and energy to do it "right".

I would guess that people that over extend (pun intended) the new functionality are the ones who program because it's their job. Even if you could go to their office and train them on the reasons why they shouldn't overuse extenders, they'll revert to overusing them because to them it's just a tool for finishing the project.

These are also, unfortunately, the same type of programmers who generally leave a company with all of their crappy code behind that the "purists" have to clean up. But that's another issue.

-ner
 
PlausiblyDamp, not to say that I don't appreciate feedback, but all you shared with me is what the new features do. I'm not just some uneducated nut who is simply opposed to change.

I used to program VB6. Then I tried C++. I started to tell myself that VB should have this and that. So many aspects seemed so much more intuitive to me. Then VB.Net came out and it had everything I always wanted in VB, and nothing more. I am in love with strict type checking; I daydream about inheritance. I understood the purpose of every addition to the language and the removal of everything that they took out.

Perhaps my problem is my experience and the new features have very little relevance. When I read about the new features, what good they do is beyond me, and all I can see is what harm they might do. The article says "C# 3.0 introduces blah, blah and blah!" but all I can see is "disaster disaster disaster." Generics have always simply intimidated me since I never really 100% got the grasp when dealing with templates in C++, but of course I can see what good they do. I am sick of casting with ArrayLists and Stacks and Queues. On the other hand, I see class definitions becoming incredibly fuzzy as they become many levels deep in inheritance and then are extended by several different classes. I see integers and booleans being compared to null all throughout code. And to be honest, when I was looking at lambda delegates and expression trees, I was simply amazed at how little the code examples resembled C#.

I am sure that you're opinion doesn't agree with mine, but at the same time I am sure that you can understand where I am coming from.
 
Last edited:
marble_eater said:
PlausiblyDamp, not to say that I don't appreciate feedback, but all you shared with me is what the new features do. I'm not just some uneducated nut who is simply opposed to change.

I used to program VB6. Then I tried C++. I started to tell myself that VB should have this and that. So many aspects seemed so much more intuitive to me. Then VB.Net came out and it had everything I always wanted in VB, and nothing more. I am in love with strict type checking; I daydream about inheritance. I understood the purpose of every addition to the language and the removal of everything that they took out.

Perhaps my problem is my experience and the new features have very little relevance. When I read about the new features, what good they do is beyond me, and all I can see is what harm they might do. The article says "C# 3.0 introduces blah, blah and blah!" but all I can see is "disaster disaster disaster." Generics have always simply intimidated me since I never really 100% got the grasp when dealing with templates in C++, but of course I can see what good they do. I am sick of casting with ArrayLists and Stacks and Queues. On the other hand, I see class definitions becoming incredibly fuzzy as they become many levels deep in inheritance and then are extended by several different classes. I see integers and booleans being compared to null all throughout code. And to be honest, when I was looking at lambda delegates and expression trees, I was simply amazed at how little the code examples resembled C#.

I am sure that you're opinion doesn't agree with mine, but at the same time I am sure that you can understand where I am coming from.

I can see where you're coming from, but these new features are optional, you don't have to use them if you don't want to. I don't personally see myself using extenders and stuff, but Generics could be interesting... All I'm really looking forward to in the next version is edit and continue - and thats mainly because its such a time saver to be able to edit some code and then continue running the app.
 
At the end of the day the decision to use any language feature is a trade off between learning how to use the feature properly and as a result knowing when to use it and deciding to stick with what you know. Knowing when to stick with an existing feature rather than use a new one is a very important skill in an industry where 'new = good' (or 'new == good') seems to be the overriding mentality - as long as there is a justifiable reason for not adopting the newer features.
In a language like C# or VB there is already a certain amount of redundancy in the language, i.e. why have a switch (select ... case in VB) statement if a simple 'if ... else if .. else' could do the same thing? Why have 'for each loops' or 'for next loops' if a while loop can do the same thing?
When these things are used correctly the overall maintainability and readablility of the code is improved, used badly, badly or just plain oddly then readabilty suffers also.

I can definately see where you are comming from but I tend to see these new features as things that can make my life easier if used correctly. As long as the tools keep pace with these additions then a lot of the confusion should be removed by compile time checking, intellisense, improvements to FxCop etc.
In your own code, be it as an individual or as a team, adopting sensible naming schemes and practices will go a long way to mitigating the confusion, as will simply avoiding things you either do not need (lambda expressions being the one feature that springs to mind)
 
Last edited:
Back
Top