|
Who says object-orientation is the sole valid way to write code? Object-orientation can get in the way when something simpler would suffice to get the job done. Extension methods allow you to add a great deal of expressiveness to your code, extend base types you don't have direct control of to provide a cleaner API, etc. etc.
Whats with all the hostility towards useful language features and non-object-orientedness? Objects don't solve every problem. Portability? Where are you going to "port" a C# or VB.NET app to...they only run on the .NET platform anyway.
Use the features for what they are. As a programmer, your job is to provide solutions to business problems in the most effective, efficient, maintainable way possible...don't get so hung up on all the "rules" and "regulations" of OOP...objects arn't the only option.
|
|
|
|
|
Interesting. I thought that C# originally was to be more OO than C++. Even in C++, you can write a completely procedural language type program (the C language). Maybe, Microsoft, in their zeal to make it easier to write software, is turning C# into an all in one language where you can get a job done any way you want. Maybe, at some later date, the keyword class will not be deprecated (not a first class item). Already, the anonymous type and var keyword are reducing the OO aspect of the language.
Then, maybe, the hardcore OO engineers will move to Java.
|
|
|
|
|
I think that the extension methods resemble more of a dynamic language features rather than procedural programming. You still need to have an object instance to call on such method and they are created for only the particular type. So an extension method added to the String class cannot be called from anything that is not a string. I think Microsoft is looking for a more dynamic language and extension methods work a little like JavaScript where you can attach new methods and properties to an existing object, but in C# it is still static and strong typing is preserved.
I know you people whine about the fact that using the extension methods I don't inherit from the said class... Sometimes you want to only add a single method, perhaps it's laziness (not good). Good thing is that in order to make your extension methods work you must put the using keyword in the file where you plan to use them. Moreover - extension method don't just float there, they themselves must be contained in a static class.
So what is the difference between creating a utility class with static methods like you would do in C# 2.0 and creating a static class with extension methods in C# 3.0? In the latter case you get cleaner syntax, being able to call the methods on the object directly, rather than passing it to a utility class method to get the same result.
All in all, I understand the concerns, but I just couldn't resist the productivity boost it gave me the first time I saw extension methods.
|
|
|
|
|
Agreed, extension methods arn't really procedural programming, but they arn't object oriented either. They DO definitely have a place, and DO definitely provide useful value when used properly. Same goes for the var keyword...it has its uses, and considering that it is local-scoped, the range of missuse of var is very, very limited.
I used to be a hard-core, object-oriented purist. It was only when I finally let go if my bias that I realized the freedom one can have when you take full and proper advantage of a language like C#. Correctly used, C# is probably the most powerful, effective language on the planet for efficiently providing solutions to business problems...and that, ultimately, is what we programmers are here for...providing solutions.
|
|
|
|
|
C# is what I call a progressive language. It started out in a very simple, Java-like form in v1.0. But it has continually evolved into a richer, stronger, more expressive language that has only served to do one thing: Improve my productivity. Hard-core OO programming is a very limiting form of software engineering. Objects don't solve everything in the simplest way...on the contrary, rich object models with full inheritance and associative relationships can get in the way of providing a simple, effective, easily maintained solution. You have to use the right tool for the job, and objects are most assuredly NOT the right tool for every job. I for one am extremely grateful that Microsoft did not allow C# to stagnate like Sun allowed Java to.
I use C# for what it is...a progressive, evolving language that has an EXTENSIVE amount of analysis and design behind it to ensure that features that are added provide benefit...not detriment. The end result, IMO, is an extremely powerful, expressive, flexible language that allows me to quickly solve problems without always having to resort to a complex OO mechanism. Sometimes, an enumerable collection of simple structures (tuples say), is all one needs to get the job done.
|
|
|
|
|
I certainly agree with that.
|
|
|
|
|
James Lonero wrote: Maybe, Microsoft, in their zeal to make it easier to write software, is turning C# into an all in one language where you can get a job done any way you want.
C++?
Sunny Ahuwanya
"The beauty of the desert is that it hides a well somewhere"
-- Antoine de Saint Exupéry
|
|
|
|
|
Jon Rista wrote: Portability? Where are you going to "port" a C# or VB.NET app to...they only run on the .NET platform anyway.
Wrong. Look up Portable.NET[^] and Mono[^]
There are also other compilation techniques out there. See IL2CPU on Cosmos[^] and Bartok used for the Singularity project.[^]
I don't understand why programmers can't seem to separate C# from .NET. C# is a programming language with a syntax and rules. The C# life cycle of your project ends after you successfully compile your project. The framework you are using then executes the compiled binaries (and it doesn't have to be IL).
Sunny Ahuwanya
"The beauty of the desert is that it hides a well somewhere"
-- Antoine de Saint Exupéry
|
|
|
|
|
I don't think people separate them, because they are so tightly integrated. C# is a language, but it is tightly integrated with the .NET framework. Thats part of what makes it such a great platform...the C# compiler simplifies the use of the framework.
Its the same with the Singularity project. Their version of C# was even more advanced than anything we have today. The C# from Singularity was a blend of C# 2.0, Cω, Spec#, with some additional features none of them had. In particular, Singularity C# made message contracts first class language citizens similar to interfaces. The C# from Singularity is far from portable in the sense your talking about...it was tightly integrated with the Singularity platform. Its also extremely powerful, and its features will probably find their way into the public C# spec at some point (woot!).
When it comes to portability between different frameworks like Mono. C# is an open, standard specification, and each version can be implemented by any third party...they just tend to be a bit delayed. I know for a fact that Mono 2.0 will include a fully compliant C# 3.0 compiler, which means code you may have written over the past year (it hasn't even been a year yet) will be portable to Mono. That includes LINQ, Extension methods, anonymous types, etc. If you require cross-platform portability, I don't think the problem is that its not possible...you just can't take advantage of new language versions until the third-parties catch up.
|
|
|
|
|
Jon Rista wrote: C# is a language, but it is tightly integrated with the .NET framework.
Is there any keyword in the C# language that suggests the use of a particular framework? What is to stop any one with the talent and time to write a C# compiler/framework that targets a currently unsupported platform?
Jon Rista wrote: you just can't take advantage of new language versions until the third-parties catch up.
So what do i do if I need to port the code right now?
Sunny Ahuwanya
"The beauty of the desert is that it hides a well somewhere"
-- Antoine de Saint Exupéry
|
|
|
|
|
"Is there any keyword in the C# language that suggests the use of a particular framework?" - Sunny
Well, LINQ syntax comes to mind. The C# compiler translates LINQ into expression trees, which are a part of the .NET 3.5 framework. LINQ is syntactic sugar for a complex framework feature. Seems to be bound to a particular framework to me.
Which is all good with me...I'd rather write LINQ syntax than build expression trees manually.
"What is to stop any one with the talent and time to write a C# compiler/framework that targets a currently unsupported platform?" - Sunny
Never said it would stop anyone...hence my discussion of Mono.
"So what do i do if I need to port the code right now?" - Sunny
If you needed to write portable code, why did you dive in and use C# 3.0?
Come on man, have some common sense. If A, then B. If you need portable code, then use a portable language version. It's a simple concept. Don't go all about being the antagonist nay-saying useful language features that, apparently, you want to use, and are just miffed that the third-party projects like Mono havn't caught up with yet. It's like your a little kid, "If I can't have it, no one will!!"
|
|
|
|
|
Jon Rista wrote:
Well, LINQ syntax comes to mind. The C# compiler translates LINQ into expression trees, which are a part of the .NET 3.5 framework. LINQ is syntactic sugar for a complex framework feature. Seems to be bound to a particular framework to me.
The foreach keyword binds to .NET's IEnumerable pattern, the lock keyword binds to .NET's Monitor.Enter/Monitor.Exit methods. There is nothing new in the C# 3 compiler translating LINQ's query expressions to .NET 3.5's expression trees. Anybody developing a compiler targeting a particular framework will decide how they want these keywords to work. Do they bind to a framework library? Do they generate their own code? etc.
Jon Rista wrote: Come on man, have some common sense. If A, then B. If you need portable code, then use a portable language version. It's a simple concept. Don't go all about being the antagonist nay-saying useful language features that, apparently, you want to use, and are just miffed that the third-party projects like Mono havn't caught up with yet. It's like your a little kid, "If I can't have it, no one will!!"
LOL.
You are right, but bear in mind that developers routinely port code someone else wrote. If I'm given a task to port C# 3 code to a C# 2 platform. I'm not going to sit around waiting for the third party platform to catch up. I should be able to do it because the .NET framework for both platforms are binary compatible.
If I run into expression trees and Linq query syntax. I'll simply write a substitute class that performs the same functionality (provided the original author properly packaged those statements in classes).
You have said good things about C# 3 and you have been correct (I personally love lambda expressions), however, we should call a spade a spade and that black sheep is called Extension methods. If their is something wrong with a product, the consumers have every right to voice their concerns and my concern is nobody except Microsoft knows how to properly use Extension methods.
If you notice they:
a) Package extension methods in exclusive namespaces.
b) Extension methods usually implement an algorithm (not a function)
c) Don't tell anyone else how to properly use it (I for one haven't seen a best practices paper on extension methods)
The goto keyword is in every major programming language but it has been repeatedly advised not to be used unless you absolutely have to. Why don't we have a "best scenarios for extension methods" paper. I'm here figuring out the best way to use this feature? Is it perhaps because Microsoft wants to wait it out and see what happens?
Also, whenever they add new "ease-of-use features" (think auto properties, partial methods and extension methods) to attract more programmers , the language dies slowly. Remember the variant data type in classic VB and how it was supposed to change the world. We all know how that turned out.
Sunny Ahuwanya
"The beauty of the desert is that it hides a well somewhere"
-- Antoine de Saint Exupéry
|
|
|
|
|
I'm still not convinced that extension methods are this evil black sheep. Were beyond issues of portability now, and into issues of coding preference, I think.
a) Package extension methods in exclusive namespaces.
aa) Where would you package them, and why would that place be better than an exclusive namespace?
b) Extension methods usually implement an algorithm.
bb) First off, implementation of the method isn't the point, its the feature itself. Second, don't all methods implement an algorithm, however simple that algorithm may be?
c) Don't tell anyone else how to properly use it.
cc) Who defines what proper use is? In what usage instances is one way proper, and what other instances is it improper?
Again, I think a little common sense works here. Extension method best practice #1: SIDE EFFECT FREE. Follow that rule, and I think your use of extension methods will be quite enjoyable, regardless of where they are packaged or whether they implement an algorithm or....well, isn't that it...algorithms? Another interesting tidbit about C# 3.0/.NET 3.5. Since .NET 3.5 is just a bunch of new API's on top of the .NET 2.0 runtime, and C# is a translator as well as a compiler, the end result is still CLI that is compatible with .NET 2.0. So long as the appropriate assemblies are available, a .NET application written with C# 3.0/.NET 3.5 should run on a system with only .NET 2.0 installed.
Sounds pretty portable to me.
Speaking of goto, I use it in two cases:
foreach (...)
{
foreach (...)
{
foreach (...)
{
if (exitCondition)
goto DoneWithLoops;
}
}
}
DoneWithLoops:
Thats a lot cleaner than having a bunch of flags that have to be checked in every loop if a complete exit from all loops is needed. C# translates complete exits from nested loops into a goto anyway in a lot of cases, so the above code is whats going to happen anyway.
switch (...)
{
case 1:
{
goto default;
}
case 2:
{
break;
}
default:
{
break;
}
}
|
|
|
|
|
|
aa) If I didn't notice Microsoft placed all related extension methods in an (almost) extension-method only namespace. I would be placing regular methods and etension methods in the same namespace.
Jon Rista wrote: b) Extension methods usually implement an algorithm.
bb) First off, implementation of the method isn't the point, its the feature itself. Second, don't all methods implement an algorithm, however simple that algorithm may be?
I mean most LINQ extension methods implement a generic algorithm that works with any object as opposed to a function that performs an action on one object. On most blogs i've read, developers want to extend a type with a function they want so badly instead of considering deriving from that type and adding the function.
cc) Since Microsoft developed this feature and must have researched it intensively, they should have at least warned us about it.
Sunny Ahuwanya
"The beauty of the desert is that it hides a well somewhere"
-- Antoine de Saint Exupéry
|
|
|
|
|
aaa) I prefer having them in their own namespace. That forces you to think about using them. To support your argument, it forces you to do something that will cause a "ported" app break at compile time if that extensions namespace isn't available. It also allows you to interchange extensions that do the same thing. If you decide you can do better than Microsoft and write the same IEnumerable extensions, that produce the same results, but perform faster...since they are in a different namespace, you can! Extension Method Best Practices[^]
In regards to inheriting to extend functionality. Inheritance is good only to a certain degree, and is not always the appropriate answer. For one, there is the ongoing Composition vs. Inheritance debate. Two, deep inheritance chains are difficult to maintain and manage. Three, your not always looking create a whole new type. You just need more functionality on an existing type. The beauty of extension methods is, if you DO inherit from an extended type, your extensions are available on all derived types too.
The only real caveat with extension methods is the possible future inclusion of a similar method name on the extended class. I havn't figured that one out yet, but I doubt I'll completely give up on extension methods because of one possible problem. Having extension methods replaced with a native method isn't necessarily a bad thing, either. For example, I have an extention method that determines if an ObjectContext for Entity Framework "contains" an entity. The result is either true or false...and the rules that determine that are static. I don't care if the implementation comes from my extension or a native implementation...I just need to know the result.
|
|
|
|
|
Jon Rista wrote: Extension Method Best Practices[^]
Thanks for that link.
Sunny Ahuwanya
"The beauty of the desert is that it hides a well somewhere"
-- Antoine de Saint Exupéry
|
|
|
|
|
Thank you.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I'd want to back up half a step.
|
|
|
|
|
well, I understand it's bothersome to define a class for each possible return type.
but in this simple case, how about:
public int[] MinMax(int[] numbers)
{
int min, max;
// Code to calculate min/max
return new int[] {min, max};
}
BTW I don't like Power Collection, they code is convilted and my implementation of RedBlackTree is 7 times faster. OK I'll share it very soon!
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station....
_________________________________________________________
My programs never have bugs, they just develop random features.
|
|
|
|
|
Elegant, indeed, and I've done this before. But it gets messy if you want to return an integer, 2 strings, and a DateTime, for example. You can create a struct to return this data, and object array (yuch), or use out parameters. Tuples just look cleaner to me.
Kyosa Jamie Nordmeyer - Taekwondo Yi (2nd) Dan
Portland, Oregon, USA
|
|
|
|
|
Yeah, it's what I mean by "it is cumbersome to create a class for all possible returns type"
I guess it's syntaxic sugar but the compiler does a lot of syntaxic sugar already (foreach/yield, var, etc...)
But the only clean implementation I can think of is to return a struct kind of
struct FunctionMinMaxReturns
{
public double Min;
public double Max;
}
And I could foresee the type explosion in the documentation if the compiler does that (because these types need to be documented for the developer's sake)
An other alternative but it works only in an untyped world, is simply to return object[] from all this tuples function.
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station....
_________________________________________________________
My programs never have bugs, they just develop random features.
|
|
|
|
|
Oh, another one; the is operator needs a complement: !is isnt aint
!( x is someclass ) is so clunky!
|
|
|
|
|
Static verification would be awesome.
Contracts[^] would be nice too if they could get some of those features in without making too much of a mess.
For instance, Spec# will throw a compile-time error (and squiggly underline in Visual Studio) with this code:
public float Divide(float x, float y)
{
return x / y;
}
But this would be valid:
public float Divide(float x, float y)
requires y != 0
{
return x / y;
}
As would this:
public float Divide(float x, float y)
{
if(y == 0)
throw new ArgumentException("y");
return x / y;
}
|
|
|
|
|
I wholly agree. Contracts will help us write less buggy code, which should be a primary focus of new C# features.
|
|
|
|
|