C##: Drowning in features

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Messages
2,097
Location
USA
To be honest I have yet to try a beta of Version 2 of C#/VB, but I have been reading about C# 2.0 and it scares me.

It seems to me that the elegance of VB.Net/C# lies in simplicity. Both languages are particularly easy to use and at the same time very powerful and flexible. But now we introduce generics, partials, and nullable types. If we continue to load these "nifty features" onto the .Net Framework/C# it won't be long before we might as well be using Managed C++.

Separating designer generated code from hand written code sounds great, but it is hardly necessary; it is already collapsed into a single line in the code editor. And I can see potential there to confuse a new programmer who never had to define a class in a single file. Form1.Designer.cs will be like this mysterious black box that creates your form for you. You will never look at it, and you will be unable to create your own form by hand because you have never been exposed to that kind of code. Just like the good ol VB6 days. I personally have run into a handful of situations where I had to hand-tweak designer generated code (mainly code for forms that contain a control that I am developing). Will the possibility of doing so even occur to someone who hasn't used C# 1.x?

Nullable types do not provide any new functionality. Instances where you need them are not that common, and surely a programmer can handle declaring their own boolean to tell them if a variable holds a meaningful value. Then, nullables add confusion in certain circumstances, like boxed nullable value types, where we can have a null reference, a null value, or a normal value.
Visual Basic:
void NullableConfusion() {
    int? X = null;
    if (ConfuseMe(X))
        MessageBox.Show("Was X a null reference or a null integer?");
}
bool ConfuseMe(Object Nullster) {
    return (Nullster == null);
    //Does this perform the == operator on Nullster as an Object or a nullable int?
}

And generics? Well, they seem nifty, I suppose. Sure, they are flexible, but I certainly wouldn't say that they are necessary.

I have yet to run into a situation where I could not make a program do what I needed it to without one of these new features. If I don't like them, don't have to use them, though, right? But the entire programming community will be and I will not be able to operate as a programmer without reasonable familiarity with these features. I will be using other people's code with these features in them. When I ask "How do I...?" on the XTreme .Net forums, someone will say "Oh, just make a generic that..." Avoiding these new features is possible but not practical.

I like nice things, but I'm not big on gadgets. These new features strike me as little more than unnecessary gadgets. More ways to do the same thing. Sure, sometimes they will provide a better way, but you have to draw the line at some point; you cannot have infinitude of program features so that every task can be performed using the absolute best method (at that point we might as well be writing in assembly). I personally draw the line at .Net version 1.1. That doesn't leave much room for improvement, but maintains the simplicity that makes .Net as great as it is. To be frank, I don't see a need for improvement in the CLR. Maybe some new classes and changes in existing classes would be nice, but beyond that I don't see VB/C# 1.1 as lacking in any way.

All that said, I can't really see with great certainty what kind of impact these new features will have on .Net programming until I see them in action, and I do plan on buying C#.Net 2005.
 
Nullable types are of primary benefit when dealing with data bases - they will prevent you having to check every field in a datareader for null before assigning to a variable. Essential - probably not, convenient definitely.

Generics give the ability to do strongly typed collections without having to inherit from one of the existing collection classes - this also removes the implicit use of object internally and the associated casting / boxing overheads.

Although splitting designer generated code into another file is one use of partial classes it is not the only use. In a large development team it may be common for more than a single developer to be working on a single class - the current one class = one file model makes this tricky to deal with. Partial classes allow this split to be done with very little fuss or effort.
 
Without the strong typing and massive performance gains of generics we'd still be using C++ at work. In fact, I'd sat all the improvements were sorely needed.

Now to blow your mind: are you ready for C# 3.0?
 
My only *gripe* about partial classes is that for the life of me I can't figure out where Microsoft is hiding it's designer generated code. But to be honest I haven't had a lot of time to play in Beta 2.0 - too busy pulling my hair out on the Enterprise Blocks - so it's probably very simple to find if I take the time.

Generics are a great idea - and sorely needed.

I'm on the fence about the null types - I agree with the data base issue - but I too am finding it hard to find a place for it elsewhere.
 
PlausiblyDamp, I appreciate your trying to be informative, but understand that I did not start this thread without first researching the new features and reading about their pros and cons and intended uses.

As far as generics are concerned: Are they useful? Of course. They offer better performance than a weakly typed collection and less code bulk than a series of class definitions for strongly typed collections. Are they sorely needed? I wouldn't say so. It isn't often that you need the performance of a strongly typed collection for unknown or very large numbers of types, and if you are truly that desparate you could create an equivalent to generics (in some aspects) by creating VB/C# code during runtime and compiling it on the fly. Much more work than a generic of course. I'm not saying generics are a bad thing. Of all the new features, generics would be the one I like the most.

As far as nullabe types, sure, they certainly have their uses, but, especially with the introduction of generics, the equivalent of nullable types could be created in a struct with a boolean and a variable (which is percisely what a generic is under the hood, only without specialized syntax). I'm not saying that nullables are a bad thing.

As far as partials, yeah, it can be useful. It certainly provides some advantages, but it can also make code harder to read and understand when a class is defined across multiple files. I'm not saying that partials are a bad thing.

What I'm saying is that too many nice things is a bad thing. There are a million and one nice things that could be added to .Net, but you don't want to have a million and one nice things. It becomes too much. It becomes complicated. It becomes C++ (there is nothing wrong with C++, it simply lacks the elegant simplicity of .Net). Consider how much more a programmer new to .Net has to learn now. With each feature you add you add a new way to introduce bugs. I am sure that partials will make it harder to find the code causing a problem. Generics are abstract which means that potential problems may not be identified. Nullables are merely a nifty struct, but giving them their own syntax in the language unnecessarily complicates the language.

Hey, If I'm the minority then by all means, throw all those nifty features into .Net. I'm a big fan of simplicity, though. I see a great amount of beauty in simplicity. I can handle the ever increasing complexity in computers and programming, but I don't have that much interest in doing so. That is why I like .Net; it is everything you need in one simple, easy to use package. Maybe if computing continues getting more and more complicated, I will break out my old Apple and go back to Applesoft BASIC.
 
In a world where difficult to read code seems to be the norm, not the exception, I think that the concept of the partial class, while "nice to have" in certian situations, has too much room for abuse and confusion. If you are writing a class that is so big that you feel it should be split into differnt files so it is easier to read or maintain, maybe that is an indicator that something is wrong? Further, if two developers are working on the same class in different files it will take much more effort to communicate among developers. If I have a conflict in CVS, I have to address it now. In a partial class I may not look at the other guy's file and next thing you know, we've implimented the same or similiar methods with different names and don't refactor nearly as often or as well as we should -- it just takes too much effort to communicate effectively with everything conveinently split that way.
 
I think you have a valid point, marble. By giving developers so much of what they want, MS has left a gap in the languages. That is, they used to have VB which served a GREAT purpose - easy to write apps with a lot of built in functionality. VB made doing hard things, easy. It may have left you plenty of opportunity to shoot yourself in the foot, but that's true in every language.

While all the new language features are GREAT for mature software developers, newcomers may find it overwhelming - and confusing - as to the best, easiest way to do something. It's one of the reasons C++ is so hard to newcomers. When you look for good quality sample code, there is a TON of error checking, pointer checking, etc. It all gets in the way of seeing what the code is supposed to be doing. Hopefully the new features in C# help to keep the code simpler and not harder to read.

I'm curious to see if MS doesn't release something like a simplified version of existing languages. If not, I'd bet that if there is a need, some company will fill it.

As for the new features, I think they're ALL great. My company has a bunch of custom classes (with a lot of code) to handle nullable value types. The partial classes aren't just for forms but ideal for any kind of designer based code generation. For example, a DataSetGenerator or a custom object builder. The idea is that ANYONE can create a builder that generates code without having to worry about how to integrate it into the existing class. As for the generics, I haven't had to use too many type safe collections. Where I have needed them, I used a simple template that replaced my class name. Sure, it's code bloat, but it works well enough. Although generics are all the talk about .NET 2.0, I think they'll be one of my least used new features.

Now if you want to talk about Visual Studio, holy cow - what an improvement! That, to me, is where the big bang for the buck comes in. The refactoring alone is worth it. I can't wait to play more with Team System. It's all just candy for developers, but good stuff still.

-ner
 
Nerseus said:
Now if you want to talk about Visual Studio, holy cow - what an improvement!
Heck yeah! I've read a lot about the refactoring features, and improved intellisense, and integrated unit testing(!), and everything else. I feel like a super geek -- I'm almost as excited about the new release of VS as I was for "Revenge of The Sith". There's going to be so much goodness in there.

I can defintely see the partial classes as being a huge imporvement for designer based coding situations. It would be great to just get rid of the clutter when you don't need it. But there is potential to take things too far -- it's not so much playing with fire as going outside without sunscreen. You can do it in small amounts, but too much sun and you'll get burned and be a little uncomfortable. I think the other mentioned "improvements" each will server their purpose. Many folks probably may not even notice they are there...
 
Generics can be useful in other scenarios as well as collections:
The typical C style Min and Max macros or a simple Swap function that take two parameters of the same type can be very easily implemented via a generic - try doing the same without them.
Generic interfaces - e.g. IComparable<T> so you do not have to provide your own object / type checks and conversions remove a chunk of cut and paste style code when compared to a non generic version. If anything I see generics reducing the amount of error checking / casting code rather than cluttering up the source.

In terms of language simplicity I feel VB.Net 2 is going more that route (default form instances being one example) but without limiting you to just the simplified approach.
 
Last edited:
VB 2.0 [will have] default form instances

Really? That used to cause me so much confusion about halfway through my VB career. It confuses how people think of objects since it introduces the conept of "things that are always there" when they're really not. I guess I should prepare for more "I need to pass a value from Form2 to Form1" questions, only this time I'll have to ask if they instantiated Form2 or took the default instance :)

As a nerd/geek myself, I think the new features are cool, but I won't be looking for ways to use them. But I want to know about them so I'll know when to use them, to save me time or energy. Hopefully that's how most people will use the new features.

-ner
 
Do the default instances use lazy initialization? Do you have a choice on a per-form basis as to whether their is a default for for that class? For instance, could I have a default frmMain but not waste memory and initialization time on a default frmIMayNeedTwentyOfTheseIMayNeedNone?
 
Default instances are defined by an attribute - if you do not apply the attribute then you do not get a default instance. As far as I am aware (do not have VS 2005 on this PC) default instances are lazy so there shouldn't be too much in terms of overhead.
 
Just talked with a coworker today who had watched the C# 3.0 show, on LINQ. Holy wow - what an idea! They're adding the ability to query just about anything, including your compiled objects.

With SQL you could query a table:
SELECT FirstName, LastName FROM Customer WHERE LastName = 'SMITH'

Now they're making it so that you can query your object. Imagine having a collection of Customer objects with FirstName and LastName string properties - write the same query to get a list of objects.

Now take this SQL:
SELECT FirstName, LastName INTO #temp FROM Customer WHERE LastName = 'SMITH'

This creates a table on the fly, called #temp, with just two columns. They have that in C# 3.0. It will create a new object on the fly, with just the properties you wanted. And, it will give you intellisense at design time - now that's just crazy!

I haven't looked into it much yet, but imagine the usefulness of a DataSet - storing data and relationship with possible cascading events, expression columns, Data "views", querying with a filter expression, etc. Now take that idea and apply it to objects.

Gotta go - I must install VS 2005 RC1 tonight and only so much time in the day...

-ner
 
LINQ does sound great. It'll really cut down on code bloat.
Implicit Typing sounds a bit superfluous but I won't complain since it simplifies initializers to close to what they were in C++:
Code:
C++
MyVeryLongClassName<MyTypeWhichIsLongToo> local;
C# 2.0
MyVeryLongClassName<MyTypeWhichIsLongToo> local = new MyVeryLongClassName<MyTypeWhichIsLongToo>();
C# 3.0
var local = new MyVeryLongClassName<MyTypeWhichIsLongToo>();
I really wish I had Extension Methods now. I always have a large utility class that perform functions on say DirectX.Vector3 for example. I'd be so nice is instead of VectorUtilities.FindPerpendicularIn3d(myVector) I could just use myVector.FindPerpendicularIn3d()...
 
I'm not big on LINQ...yes, for the lazy programmer it's great. But think about what it must be doing under the hood...how can it possibly perform as great as well generated for or while statement? Also, how many of us are use to doing things the way we are? Now they throw in this syntax to almost 'make' us do things differantly...do we have to? Of coarse not, but will all the newbie's who don't understand the differances in performance using differant type of loops understand why they're program crawls because they used this new syntax? I mean if it compiles to the same IL that a indexed for loop compiles to; great - but I just don't like it... it doesn't sit right with me...but it is a cool idea. But it all goes back to the theory of just because something can be done, should it?
 
The most important thing to keep in mind is that programming is easier when the code expresses what you're thinking. Ideally, you want code that looks like pseudo-code in terms of readability. When it's that easy to understand then you're less likely to have errors in your code. Most of the latest advancements in .NET, and programming in general, are heading in that direction. For example, refactoring tools aren't just hype - they help make code more readable. More readable means less errors (hopefully).

Performance is definitely the trade-off for all of this so it's good to keep in mind. You wouldn't do something that's obviously bad performance, but you also don't need the old school style of thinking where you must design for performance, CPU cycles or even memory consumption.

This is all for "normal" business programming of course. For real-time programs, games, handheld devices and other specialty areas you may have other priorities.

-nerseus
 
On the subject of taking code to a higher level, I recently read something about UML support in VS2005. Does anyone know the extent of the support? Are we talking code generation or will it just be picture drawing? What about reverse engineering?
 
Code generation and reverse engineering are built in via the class designer. It doesn't come close to supporting all the UML document types though so if you like sequence diagrams etc you will need to resort to 3rd party tools.
 
Back
Top