Groups | Blog | Home
all groups > dotnet framework > march 2008 >

dotnet framework : Extension Methods in .NET - A Comment


Peter Duniho
3/29/2008 3:42:11 PM
On Sat, 29 Mar 2008 15:21:53 -0700, Axel Dahmen
[quoted text, click to view]

You're welcome to your opinion, even if you cannot be bothered to express
it in a polite, respectful way. Nevertheless, suffice to say your opinion
is just that: merely your opinion. Many people can and do disagree.

One particular example: much of what LINQ provides would not work without
extension methods. It relies on it heavily.

But regardless, no one's forcing you to use them. If you don't like them,
then don't use them.

Peter Duniho
3/29/2008 6:36:02 PM
On Sat, 29 Mar 2008 18:26:18 -0700, Axel Dahmen
[quoted text, click to view]

Rather than the contrived response you attribute to them, I would guess
that they would (gently, you hope) explain to you that extension methods
are NOT a "member function" of the class being extended.

If they were, they'd have access to the class's private and protected
members, which they don't.

Extension methods are little more than a syntactic shorthand for writing a
method that takes an instance of some class and performs some operation
using that instance, using only the public members that'd be available to
any other non-member method. People are already writing exactly that kind
of method on a regular basis. All that extension methods do is make the
code that uses that technique more concise.

As Gregory said, you would have more credibility as a detractor of
extension methods if you appeared to be coming from an informed position.
Right now, you certainly don't seem to be.

Cowboy (Gregory A. Beamer)
3/29/2008 7:23:05 PM
First, extensions methods make things more elegant, as detailed by Jon
Skeet. If you dig deep enough, they are an "extension" of delegates, which
is not a slap in the face of OO.

Second, extension methods are the least kludgy way to work with objects in
LINQ. Without extensions methods, LINQ would be both verbose and rather
neutered.

Used incorrectly, extension methods become a major cluster f***, but so do
most technology innovations.

Perhaps you should hold your comments until you have a firm grasp of how
they are used and why. Then, you will find that they are not so insidious
after all. True, an ignorant and/or stupid developer can misuse them and
kludge things up, but a hammer can be used to cave someone's head in; it
does not make hammers stupid. Just my two cents.

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

Subscribe to my blog
http://gregorybeamer.spaces.live.com/lists/feed.rss

or just read it:
http://gregorybeamer.spaces.live.com/

*************************************************
| Think outside the box!
|
*************************************************
[quoted text, click to view]
I've just read into Extension Methods in .NET and can't hold to give a short
comment on them:

Using static classes to purely use another class's fields and methods to
even pretend being a member of that other class without actually being a
member of that class is very hard to understand. It compromises any
refacturing effort. Who invents such things...?

OOD/OOA in mind, to me Extension Methods seem to be the virtually dirtiest
workaround for circumventing multiple inheritance I've seen so far.

Extension Methods in .NET is a slap in the face of all serious software
engineers.

www.axeldahmen.com
Axel Dahmen

Peter Duniho
3/29/2008 8:15:50 PM
On Sat, 29 Mar 2008 19:11:20 -0700, Axel Dahmen
[quoted text, click to view]

That's not what I wrote.

[quoted text, click to view]

I know. And based on what you've written here, it really doesn't seem as
though you understand what extension methods do.

[quoted text, click to view]

I'm not convinced. Perhaps you could post a valid, complete example of
what you mean. Certainly the other example isn't nearly as graceful as
using extension methods would be, given that you'd have to wrap some
existing class in the generic class you seem to be proposing in order for
it to work as the code you posted shows.

[quoted text, click to view]

They can ask that all they want. If they are dealing with a class that
they don't own, that's simply not possible. And if they are dealing with
a class that's sealed, they cannot even sub-class the class in order to
add the method. And even if they can sub-class the class, that would
require instantiating the sub-class in order to call the method on the
class.

In other words, extension methods are addressing a very specific scenario,
one that is not addressable at all by the alternative you propose as
superior.

The fact is, it does not break OOP principles to have a static method that
takes as a parameter an instance of some other class and does something
with that instance. People have been writing that kind of code in OOP
languages since OOP languages have been around. And that's all that an
extension method is, except with a syntax that is more concise.

As Jon already pointed out, it's not like people should be going around
using extension methods willy nilly. And of course, as is the case with
all language conveniences that have been present since programmers moved
past writing their code as individual ones and zeroes, it's important to
understand the nature of what one is writing. For example, if you use the
LINQ extension method Count() on an IEnumerable<T> instance, you need to
understand that IEnumerable<T> does not itself offer a direct access to
the count of elements, and thus there could be significant overhead to
counting an enumerable class.

But none of that suggests that extension methods are in any way flawed,
and certainly not that they are a "slap" in anyone's face. It just means
that you have something new to learn if you expect to be proficient in the
latest .NET technologies.

Frankly, all of the complaints in your original post -- that extension
methods in some way "pretend" to be a member of another class (they don't
do any such thing...they simply use an instance of another class as any
other code not in that class could use it), that it compromises any
"refacturing [sic]" effort (did you mean refactoring? in any case, it
doesn't prevent refactoring at all), that they are a workaround for
circumventing multiple inheritance (extension methods have nothing to do
with multiple inheritance), and your most profane assertion that they are
a "slap in the face of all serious software engineers" (really? I don't
feel slapped...are you telling me I'm not a serious software engineer?) --
are without merit.

Whether you and your coworkers wind up writing your own extension methods
is a matter of your own internal discussions. Certainly if one is going
to use them, there ought to be a good reason for it. I rarely have code
that could benefit from the use of extension methods. But to rant against
them as you have, especially when you don't appear to really understand
what they do in the first place, all that's going to do is cause needless
friction between you and other programmers.

It may well still be fashionable for programmers to carry themselves with
such anti-social attitudes, but I can assure you that it's not likely to
be a positive contribution to your career to act that way. If you're
going to argue against extension methods, at least learn enough about them
so that you have arguments against them that make some sense.

Jon Skeet [C# MVP]
3/29/2008 10:39:36 PM
[quoted text, click to view]

Personally, I think they're great - when used appropriately.

They can greatly enhance the readability of code, and LINQ is a great
example. Which do you think is clearer:

1) Without extension methods:

IEnumerable<string> names =
Enumerable.Select(
(Enumerable.Where(people, person => person.Age > 17),
person => person.Name);

or

IEnumerable<string> names = people.Where(person => person.Age > 17)
.Select(person => person.Name);

?

The latter gives a much clearer indication of the order in which the
transformations will take place, as well as being more concise.

Yes, extension methods can be abused. However, they allow a lot of
really *nice* uses too - and enriching interfaces (as LINQ does) is
probably the best use going.

Of course, you can avoid using them yourself - but personally I'll use
them (sparingly) to write more readable, maintainable code.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Axel Dahmen
3/29/2008 11:21:53 PM
I've just read into Extension Methods in .NET and can't hold to give a =
short comment on them:

Using static classes to purely use another class's fields and methods to =
even pretend being a member of that other class without actually being a =
member of that class is very hard to understand. It compromises any =
refacturing effort. Who invents such things...?

OOD/OOA in mind, to me Extension Methods seem to be the virtually =
dirtiest workaround for circumventing multiple inheritance I've seen so =
far.

Extension Methods in .NET is a slap in the face of all serious software =
engineers.

www.axeldahmen.com
Axel Dahmen
3/30/2008 3:14:25 AM
Hi Jon,

thanks for your reply.

How about keeping the better syntax but without Extension Methods?

As far as I can see, a generic could have done the trick here:

Linq<People> people;

IEnumerable<string> names =3D people.Where(person =3D> person.Age > 17)
.Select(person =3D> person.Name);

Regards,
Axel Dahmen

Axel Dahmen
3/30/2008 3:26:18 AM
Hi Peter,

[quoted text, click to view]

You're right. It's not one of my strengths to be eloquent when I see a =
bad design decision. I apologize for that. I'd like to hear opinions of =
those who disagree. Particularly how they want to explain Extension =
Methods in OOD terms. How can someone possibly argue about keeping an =
objects methods within the object (a typical OOD pattern) while at the =
same time accepting Extension Methods?


[quoted text, click to view]

I guess so. That's just why they invented it. There's not other possible =
reason for it that I could think of... Still it's a wrong approach. The =
same Linq syntax could have been achieved with other, more OOD, =
practices.


[quoted text, click to view]

You got me wrong, I'm afraid. My argument is not about using them. It's =
about arguing with colleagues about using them. If I tell them to keep =
member functions within a class instead of creating some function =
anywhere, providing an object as a parameter, doing nothing else than to =
handle the object's properties, what will they say? "Must be a valid =
pattern. MS and millions of others are using it!" How am I (or any other =
Software Engineer) supposed to argument on this?

Regards,
Axel Dahmen
3/30/2008 3:44:33 AM
Hi Gregory,

thanks for your reply as well.


[quoted text, click to view]

Please refer to my reply to Jon.


[quoted text, click to view]

They are. Please refer to my reply to Peter.


[quoted text, click to view]

Again, please refer to my reply to Jon. They are unnecessary. It would =
be possible keep the pretty syntax without using them.


[quoted text, click to view]

I agree with you here. Everything must be used in a reasonable way.


[quoted text, click to view]

Usually I would have agreed this to be a perfectly fine suggestion of =
yours. And it still is.

However, as I wrote Peter, it's not the usage. The usage within Linq is =
fine. But implementing own Extension Methods, that's a slap in the face. =
It's the concept. And I still believe that Linq would have had the same =
syntax without invention of Extension Methods.


[quoted text, click to view]

I perfectly agree with you. I will use them (in Linq) and I'll like Linq =
because of its usage. But I won't get to like Extension Methods as they =
contradict OOD paradigm of keeping an obvious member function within the =
class itself.

And, sure, things can be very much abused with anything. But creating =
custom Extension Methods would be such abuse. They shouldn't have been =
invented. A generic would have done the trick. Or the invention of =
multiple inheritance. Both OOD conform. But to argue on this I'd, as you =
wrote, get more acquainted with Linq first.

After all, like Peter wrote, it was just my opinion. But an opinion I =
believe that should be seriously considered.

Regards,
Axel Dahmen
3/30/2008 4:11:20 AM
Thanks Peter,

you are right. I should get more into Linq before arguing. In fact, I'm =
not arguing against Linq or its syntax, but against Extension Methods =
themselves. I'm quite confident that Linq could have been as gracefully =
been implemented without the invention of Extension Methods. If a =
pattern like Extension Methods are used on a wide bases, as you wrote, =
then programmers should ask themselves if they shouldn't move these =
methods into the objects' class definition itself =
(http://www.refactoring.com/catalog/moveMethod.html).

Regards,
Axel Dahmen


---------------------
"Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> schrieb im Newsbeitrag =
news:op.t8s2qcmd8jd0ej@petes-computer.local...
[quoted text, click to view]
Jon Skeet [C# MVP]
3/30/2008 7:45:52 AM
[quoted text, click to view]

That only works if you start with a Linq<People> - it won't work on all
the many existing enumerable collections. It also forces each of those
methods to expose that they're returning a Linq<People> as well.

Being able to operate on arbitrary IEnumerable<T> is very, very useful
- and you can apply the same technique to other interfaces.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Jon Skeet [C# MVP]
3/30/2008 7:50:53 AM
[quoted text, click to view]

Very, very simply:

1) Not all actions which logically act "on" an object need to change
that object's state

2) Not all actions which are desirable in terms of appearing to act
"on" an object can be anticipated by the class's original designer

3) Using inheritance to add these kinds of actions isn't always
possible, and inheritance comes with many penalties in terms of design.

Traditionally, static methods have been the way of getting round this -
I'm sure you've seen utility classes just full of methods to operate on
streams, or strings etc. Extension methods just means that when you use
the methods in those utility classes, they're available in a more
transparent way.

Unless you're actually debugging into the method in question, you don't
really need to know whether it was provided by the original class or as
an extension method. When you need to know, it's easy to find out -
when you *don't* need to know, the more natural syntax aid's
readability.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Alex Clark
3/30/2008 6:43:04 PM
Axel,

[quoted text, click to view]

No, it would not be possible without some major breaking changes to the
framework. LINQ is effectively grafted *on* rather than *in* to
IEnumerable, and this was only possible via extension methods. LINQ can be
cumbersome enough as it is without having to make the syntax totally
unreadable by means of passing original collections into LINQ static methods
and have them return filtered IEnumerables. Generics simply wouldn't cut it
as a solution.

[quoted text, click to view]

How could it possibly maintain its syntax without Extension Methods? The
only alternative is to actually embed the methods onto the original
IEnumerable classes rather than providing what is essentially a LINQ
exo-skeleton for the IEnumerables. Doing so would've meant big changes to
the classes in question. I'd rather know my 2.0 code is still going to run,
thankyou very much.

As for "implementing own Extension Methods", presumably you mean to say that
you feel MS has slapped us in the face by giving us the option of writing
methods to extend classes we don't have the source code to, and which could
potentially even be sealed? Why is that a bad thing?

I've spent some time rewriting a few utility "helper" classes here and there
to be simple modules full of Extensions, and it's improved the syntax in
large areas of my app considerably as well as making coding a lot more
intuitive. Saying goodbye to the infamous "SqlHelper" class was a happy day
indeed as far as I'm concerned.

[quoted text, click to view]

Wuh oh, paradigm violation, someone call the partyvan... :-D

[quoted text, click to view]

If you genuinely believe Generics alone could have been used to implement
LINQ with identical syntax, I suspect you still don't fully understand what
Extension methods do and are for. As for multiple inheritance, I would
strongly question as to whether that does truly conform to OOD in this day
and age. Multi-inheritance creates a dizzying array of new problems to be
solved, and again doesn't create the same elegant syntax of extension
methods.

Perhaps you could explain how you think either Generics or Multi-Inheritance
could be used to mimic the current syntax of LINQ without breaking
compatibility?

Having a LINQ<T> class that surrounds existing generic collection classes
would look awful:

Dim myList as Linq(Of Generic.List(Of MyType))

....and now your IEnumerable is actually of type Linq rather than List, which
will impact your code if you're passing that as a parameter anywhere else.

Multiple inheritance? Presumably you'd then have (for example) a List<T>
class in the framework that inherited from its regular base class,
implemented IEnumerable, *and* inherited from a Linq base class? But then
it's no longer strictly the same type as the v2.0 List<T> class, so you
break masses of code.


Remember that .NET 3.5 is essentially v2.0 with bolt ons, one of which is
LINQ. It still has to be backwards compatible. I can see how extension
methods were born of necessity for the purposes of injecting LINQ into the
framework in a non-breaking manner, and some might call it a kludge, but
it's one I welcome with open arms.

There's a lot of weird, badly implemented and overly cryptic crap in .NET
3.5 --- things I think we could have done without, things that are heading
in the wrong direction, things that are just down right not finished yet and
shouldn't have been released. LINQ and all its many framework-enhancing
children however is not on that list. In my opinion, anyway ;-)

-Alex


Peter Duniho
3/31/2008 4:07:43 AM
It seems to me that the whole discussion boils down to this:

On Sun, 30 Mar 2008 22:52:29 -0700, Axel Dahmen
[quoted text, click to view]

No one has suggested extension methods be used except in the very specific
scenario I describe above. They in fact CANNOT BE USED IN ANY OTHER
SCENARIO. And you have specifically written here that in that scenario --
THE ONLY ONE IN WHICH EXTENSION METHODS CAN BE USED -- you agree with me.
So what's your problem?

Given the above, the only possible way you could have a disagreement with
the use of extension methods is for you to not understand them. Because
you've specifically stated that you agree with the one thing that
extension methods do. There's nothing left to disagree with, except
things you've imagined extension methods do but which they don't.

Regardless, here's the bottom line: extension methods are here to stay.
You are welcome to not use them, but you will have to accept the fact that
your anti-extension method attitude puts you in a very tiny minority. If
you want to spend the rest of your career debating the issue with others,
that's your choice. But it's really a waste of your time. You'd be much
better off just finding a new job where you don't have to worry about
using them.

In any case, you've established very well in this thread that you don't
understand extension methods. If and when you're willing to accept that
fact, then it might be productive to continue the conversation. Until
such time however, it's obviously a waste of time to try to discuss the
issue with you. It's impossible to find any common ground from which to
debate the finer points as long as you continue to invent things that
aren't true about extension methods in your pursuit of criticism of them.

Axel Dahmen
3/31/2008 7:52:29 AM
[quoted text, click to view]

Believe me, I did.


[quoted text, click to view]

Sure, here's is a simple example. I've nailed it together in a couple of =
minutes so don't look too closely. Yet it does the job:

- MyLinq.cs (this is a sample Linq implementation) =
-------------------------------------------------------------------------=
---
using System.Collections;
using System.Collections.Generic;

namespace LinqTest
{
class MyLinq<T> where T:class
{
private Queue<T> _coll;

public MyLinq(Queue<T> coll)
{
_coll =3D coll;
}

public int Count()
{
int retVal =3D 0;

foreach (T o in _coll) ++retVal;

return retVal;
}

public MyLinq<T> Select()
{
Queue<T> retVal=3Dnew Queue<T>();

foreach(T o in _coll) retVal.Enqueue(o);

return new MyLinq<T>(retVal);
}
}
}
-------------------------------------------------------------------------=
----

- Person.cs =
-------------------------------------------------------------------------=
---
namespace LinqTest
{
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
-------------------------------------------------------------------------=
----

- Program.cs =
-------------------------------------------------------------------------=
---
using System;
using System.Collections.Generic;

namespace LinqTest
{
class Program
{
static void Main(string[] args)
{
Queue<Person> persons =3D new Queue<Person>();
=20
persons.Enqueue(new Person { FirstName =3D "Peter", LastName =3D =
"Ustinov" });
persons.Enqueue(new Person { FirstName =3D "Bart", LastName =3D =
"Simpson" });

MyLinq<Person> linq =3D new MyLinq<Person>(persons);

Console.WriteLine(linq.Select().Count());
}
}
}

-------------------------------------------------------------------------=
----

The last line is the most important as it looks almost exactly like =
Linq, but it has been implemented in an object oriented fashion.



[quoted text, click to view]

I don't see a difference..... Where do you see it?


[quoted text, click to view]

That's why it's sealed. What did you think?? When someone says "Turn =
right here!" are you turning left then?


[quoted text, click to view]

There's no point in what you're saying. The concept of Expansion Methods =
isn't magic. You need to instanciate an object to use methods on it =
there as well.


[quoted text, click to view]

Yes, a scenario like "no rules".



[quoted text, click to view]

I agree with you here. But there is a very tiny area where they should =
be used. Creating polymorphic factories, for example. Anything else is =
usually procedural code dressed as OOD.


[quoted text, click to view]

So where's your point? I've added a Count() property to my above =
example.


[quoted text, click to view]

Apparently you didn't understand Expansion Methods. In fact the only =
purpose of them is in fact to pretend to be a member of another class. =
Anything else can be done without this new syntax. You don't need =
Expansion Methods to implement static methods that interact on other =
objects. But you need Expansion Methods to syntactically pretend these =
static methods would belong to another object.


[quoted text, click to view]

Found a typo? Cool... you may keep it.

I disagree. The concept of Expansion Methods contradict any refactoring =
efforts. It compromises the "Move Method" paradigm.

Regards,
Rory Becker
3/31/2008 7:57:04 AM
Hello Axel,

[quoted text, click to view]

IMHO... Sealing a class has less to do with stopping you inheriting from
it and more to do with ensuring that someone doesn't fundamentally alter
the way it works and breaking methods that depend on params of that type.

For example if you could inherit from string you would be able to create
a derived string that fundamentally broke the internasl of it and would still
be passable to methods that required a string.

Extension methods don't give you anything like this level of access, but
allow you to enhance the the string class additively.

This is not a bad thing.

--
Ror

Axel Dahmen
3/31/2008 8:06:07 AM
[quoted text, click to view]

You are right.

Regarding 1): That's common usage. But functions that mainly interact =
with some other object's properties should be move to the object (or a =
derivate). They can, of course, be implemented somewhere else, but this =
shouldn't be a common usage.

Regarding 2): In fact, they *can't*. That's what inheritance is made =
for.


[quoted text, click to view]

I fully agree with you. That's the purpose of Expansion Methods. Yet I =
didn't use any such utility classes ever (except for testing or when I'm =
in a hurry). Using these is a procedural way of thinking, but not OOD.

Well, OK, I see a point when programming in VB because this language has =
been procedural for a long time now. OOD is new there and probably not =
necessary. I must admit that I'm solely thinking of C# and the .NET =
framework in my argumentation.


[quoted text, click to view]

It does, for sure. ...given that such static methods have been =
implemented in the first place. Which is what should be avoided (which =
is the more or less abstract topic of my thread).

Regards,
Axel Dahmen
3/31/2008 8:47:10 AM
Hi Alex,

[quoted text, click to view]

Please refer to my sample to to Peter here. The simple syntax is kept =
without using Expansion Methods.


[quoted text, click to view]

So let me ask you another question then: *Why* have they been sealed in =
the first place? Wouldn't it be better then to have MS remove the =
sealing? If a class has been sealed then it has been done for some =
reason. A wrong decision here shouldn't been worked around, it should be =
corrected. From design perspective a mistake doesn't become better by =
creating a workaround. It gets getter by correcting it. I personally =
prefer to drive just right instead of straight, right, right, right. =
Three times right doesn't make something "more right". ...See my point?


[quoted text, click to view]

Could I see your SqlHelper class? I believe SqlHelper usage could be =
replaced with some other solution.


[quoted text, click to view]

Yes right, but that's why we've studied informatics, didn't we? I'm =
serious. Although I'd love to return the smiley ;)


[quoted text, click to view]

I do. They are to cover bad (prodecural) coding. ...Let me restrict =
"bad" to OOA. As I wrote in my post to Jon, it may not fully apply to =
Visual BASIC. That language was procedural for a long time.

[quoted text, click to view]

I'd leave that for discussion. And I fully agree with you, it would =
definitively be a challenge for the CLR development team.


[quoted text, click to view]

Please refer to the sample I've given to Peter in my last post.


[quoted text, click to view]
else.

No.. The Linq class could be derived from, e.g., List and could be used =
anywhere.



[quoted text, click to view]

No. I was thinking of some class that implemented Linq and another class =
that implemented, e.g., a Person collection. A derived class could then =
inherit both and provide a merged functionality. I could have used such =
a thing very often when providing custom databinding functionality to =
ASP.NET Web Server Controls in .NET 1.0.

But I'm not sure about multiple inheritance any more. Generics might be =
sufficient to do the trick.


[quoted text, click to view]

Me, too. I fully agree with you here. Well, almost. I still believe they =
could have come up with somthing more OOA and still provide the same =
functionality for Linq.

Extension Methods is building a concept to disguise procedural code as =
OOD. I'm not arguing about the pretty Linq syntax. I'm just arguing =
about how it was achieved.


[quoted text, click to view]

Yes, I fully agree with you, Alex. A agree some things (O/R Designer, =
AJAX control extender [which is the same bad concept as Extension =
Methods]) have been shot out too quick.

Anyway, just my opinion as well ;)

Regards,
Jon Skeet [C# MVP]
3/31/2008 9:04:20 AM
[quoted text, click to view]

Using inheritance unnecessarily to add functionality is:

a) impossible in many situations (e.g. when the class is sealed)
b) undesirable in many other situations

Personally I prefer most classes to be sealed - there is a design cost
to inheritance, which should not be overlooked. See

http://msmvps.com/jon.skeet/archive/2006/03/04/inheritancetax.aspx

[quoted text, click to view]

No - inheritance is made for *specializing* behaviour, not representing
other behaviour which is still appropriate to *every* instance of the
base type.

[quoted text, click to view]

Extension methods, not expansion methods.

[quoted text, click to view]

Two examples in my own experience:

1) String utility routines. We can't derive from string, nor could we
force every instance of string returned by the library methods to be an
instance of our own string type even if we could. Where, then, would
you write utility methods for strings? Such methods are *very* common.

2) Stream routines, e.g. to read the whole of a stream into a byte
array, or copy the contents of one stream to another. These are very
commonly mis-implemented operations, so it's good to have them in one
place. They can operate on *any* stream, so inheritance is
inappropriate. Static method taking a stream is entirely consistent
with this situation - and extension methods make them easier to use.

[quoted text, click to view]

Okay, so really you want to virtually abolish static methods. Sorry,
can't agree there. I rather like being able to use LINQ operations on
*any* IEnumerable<T> rather than having to construct an instance of
MyLinq<T> every time. It sounds like you want to force people to
artificially create an instance of a type for *no reason* other than to
avoid using static methods.

I don't think that's a pragmatic or sensible approach.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Jon Skeet [C# MVP]
3/31/2008 9:08:47 AM
[quoted text, click to view]

<snip>

[quoted text, click to view]

But *then* it's restricted to Lists - what happens if I've got an array
instead? And if the Linq class were to derive from List, you'd have a
*really* broken inheritance chain. In order to compose operations, each
chaining operator would have to return an instance of a type which
implemented the other operators. Now, you don't want Linq.Where to
return a new Linq if Linq is derived from List, because you're not
actually trying to return a new List - part of the point of LINQ is the
data streaming model, where you *don't* copy the whole of the data
every time you do an operation.

So instead you have to return something else implementing the same
interface as Linq - and probably reimplementing most of the operators
in a virtually cut and paste fashion.

Nope, I think the "it works on any IEnumerable<T> and the code is only
in one place" model is *much* more appealing.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Jon Skeet [C# MVP]
3/31/2008 9:10:43 AM
[quoted text, click to view]

<snip>

It does the job if you don't mind the fact that it copies all the data.
If I write:

someData.Where(firstCondition)
.Where(secondCondition)
.OrderBy(firstOrdering)
.ThenBy(secondOrdering)
.Select(projection)

then I only want one item of data to be copied at a time. Your
implementation breaks that completely.

I think you have missed some of the fundamental points of LINQ to
Objects.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Patrice
3/31/2008 12:59:37 PM
Also keep in mind anyway that they are pretty much nothing more than
syntactic sugar...

This is basically another notation for MyHelpMethod(MyInstance) so that you
can write MyInstance.MyHelpMethod instead...

--
Patrice

"Axel Dahmen" <keentoknow@newsgroup.nospam> a écrit dans le message de news:
6CB34136-A7A9-481C-98FE-8A938D39A20D@microsoft.com...
Hi Peter,

[quoted text, click to view]

You're right. It's not one of my strengths to be eloquent when I see a bad
design decision. I apologize for that. I'd like to hear opinions of those
who disagree. Particularly how they want to explain Extension Methods in OOD
terms. How can someone possibly argue about keeping an objects methods
within the object (a typical OOD pattern) while at the same time accepting
Extension Methods?


[quoted text, click to view]

I guess so. That's just why they invented it. There's not other possible
reason for it that I could think of... Still it's a wrong approach. The same
Linq syntax could have been achieved with other, more OOD, practices.


[quoted text, click to view]

You got me wrong, I'm afraid. My argument is not about using them. It's
about arguing with colleagues about using them. If I tell them to keep
member functions within a class instead of creating some function anywhere,
providing an object as a parameter, doing nothing else than to handle the
object's properties, what will they say? "Must be a valid pattern. MS and
millions of others are using it!" How am I (or any other Software Engineer)
supposed to argument on this?

Regards,
Axel Dahmen

Alex Clark
3/31/2008 2:41:52 PM
[quoted text, click to view]
I fully agree with you. That's the purpose of Expansion Methods. Yet I
didn't use any such utility classes ever (except for testing or when I'm in
a hurry). Using these is a procedural way of thinking, but not OOD.
[quoted text, click to view]

So you've honestly never used static methods for anything? No static class
containing methods to handle, say, string-formatting specific to the data
you're dealing with? I would like to know how you've avoided creating
utility/helper classes & functions all these years, but I truly hope it's
not just a case of "I put them all into a formatting class which I
instantiate and call the methods of as needed"...

[quoted text, click to view]
Well, OK, I see a point when programming in VB because this language has
been procedural for a long time now. OOD is new there and probably not
necessary. I must admit that I'm solely thinking of C# and the .NET
framework in my argumentation.
[quoted text, click to view]

I think this is indicative of you not understanding the framework. VB has
existed for much, much longer than C# and had the beginnings of OOD as of
version 4 (mid 90s?) when MS first introduced classes into the language.
When .NET was released, C# and VB.NET were released at the same time. Both
support an identical set of OOD tools. VB.NET is no more or less procedural
than C#, it's just a different syntax of what is essentially the same
language under the hood. OOD is no newer in VB.NET than it is in C#, and
arguably it's existed in VB for longer due to VB's age.

In fact, .NET was in Beta back in 2000, so I wouldn't class 8yrs of OOD in
either language as being particularly *new*, unless you're only just
starting to use the framework yourself?

[quoted text, click to view]
....given that such static methods have been implemented in the first place.
Which is what should be avoided (which is the more or less abstract topic of
my thread).
[quoted text, click to view]


Which causes me to raise my earlier question once again: have you honestly
gone through life as an OOD programmer and avoided static methods as though
they carry some form of disease? When there is a need for utility and
helper functions, how have you implemented these?

Regards,
Alex

Jon Skeet [C# MVP]
4/3/2008 8:05:40 AM
[quoted text, click to view]

They are *fundamentally* different from LINQ.

[quoted text, click to view]

Look at what your code does.

public MyLinq<T> Select()
{
Queue<T> retVal=new Queue<T>();

foreach(T o in _coll) retVal.Enqueue(o);

return new MyLinq<T>(retVal);
}

What would happen if you passed an infinite sequence into that? LINQ
would handle it absolutely fine. Your code wouldn't.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Axel Dahmen
4/3/2008 8:28:25 AM
Hi Rory,

[quoted text, click to view]

That would only be possible if string provided virtual methods to be =
overridden. And this again would be a deliberate design decision. If =
string provided virtual methods then they are supposed to be overridden. =
And overriding shouldn't break a class. If it did then it's a design =
flaw of the class.

Usually to prevent overriding methods from breaking base class code, the =
base class methods are *not* marked virtual but call an empty virtual =
method instead, like:

private void MustExecute()
{
// do necessary stuff ...

CanOverride();
}

public virtual void CanOverride()
{}


Axel Dahmen
4/3/2008 8:33:59 AM
[quoted text, click to view]

No, why should it? In fact, it does nothing else Linq does. How do you =
think Linq is implemented? Probably the method examples I gave weren't =
optimized but that doesn't make them basically different from Linq.

Again, Linq is no magic. Extension Methods makes it look magic, but it =
isn't.

Axel Dahmen
4/3/2008 8:36:54 AM
[quoted text, click to view]

No, I didn't agree on using Extension Methods. I agreed on the fact that =
static methods take other objects as parameters. In fact, every function =
having parameters does that.

Stop flaming!

Jon Skeet [C# MVP]
4/3/2008 9:06:50 AM
[quoted text, click to view]

And yet you're happy to introduce inheritance all over the place
unnecessarily, it seems, just to avoid static methods.

[quoted text, click to view]

You haven't answered most of the problems of inheritance though, nor
have you considered the possibilities of new methods which hide
existing methods instead of overriding them.

I'm still happy with sealed classes, and wish it were the default in
C#.

[quoted text, click to view]

LINQ to Objects is the *obvious* example. The idea of filtering (Where)
or projecting (Select) is valid for all IEnumerable<T>. Why should I
restrict it to a particular derived class.

[quoted text, click to view]

One is a technically correct term, the other isn't.

[quoted text, click to view]

Pretty much every project I've worked on in .NET and Java has had
things like this. StringBuilder is a class which works on a string
repeatedly - I'm talking about methods like "escape with backslashes"
or "encode HTML entities" etc.

[quoted text, click to view]

With extension methods, I can use LINQ to Objects with any
IEnumerable<T>. With your suggested "solution" I'd have to create a new
instance of some derived class *every time I wanted to do anything*,
completely unnecessarily.

[quoted text, click to view]

No, I don't see that at all - not when they're used judiciously. If
they're used all the time, completely arbitrarily, they'll cause issues
- but the same is true for anything (and particularly true for
inheritance, by the way - the deeper the inheritance hierarchy, the
harder debugging is IME).

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Jon Skeet [C# MVP]
4/3/2008 9:32:35 AM
[quoted text, click to view]

Our LINQ operators work in a different way, which has advantages in a
few situations, but make life more complicated in others.

[quoted text, click to view]

The "agnostic" side is that I can still use a C# query expression with
my own LINQ implementation. C# doesn't care where the
Select/Where/SelectMany etc methods come from.

See
http://msmvps.com/blogs/jon.skeet/archive/2008/01/04/quot-push-quot-
linq-revisited-next-attempt-at-an-explanation.aspx

for more on this.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Jon Skeet [C# MVP]
4/3/2008 9:33:26 AM
[quoted text, click to view]

Um, yes.

[quoted text, click to view]

I never mentioned implicitly typed local variables. Where did you get
the idea that I was talking about them?

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Jon Skeet [C# MVP]
4/3/2008 9:41:38 AM
[quoted text, click to view]

Without extension methods (and without actually putting all the LINQ
query operators as part of IEnumerable<T> itself, which would be a
crazy burden on implementors) you couldn't write:

mySource.Where(x => x.Length > 5)
.Select(x.ToUpper())

(and all the other query operators, of course)

with mySource as any of:

Stack<string>
string[]
List<string>
or basically *any* IEnumerable<string>

The ability to work on *any* IEnumerable<T> without having to create an
intermediate wrapper class or something similar is part of the elegance
of LINQ in my view.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Axel Dahmen
4/3/2008 9:45:41 AM
[quoted text, click to view]

You are right. I'd even go further: I'd say that doing *anything* =
unnecessarily is undesirable in many situations. ;)


[quoted text, click to view]

I've read your interesting article. Please refer to one of my recent =
posts here from today regarding how to keep a design stable without =
sealing.


[quoted text, click to view]

Again I agree with you. Could you give a quick example of > representing =
other behaviour < that's appropriate for this discussion? I frankly =
can't see an issue here.


[quoted text, click to view]

Yep, right. Got to hurry over the keys sometimes... Yet, where's the =
difference?


[quoted text, click to view]

Is this really common? I've never seen some kind of StringHelper class. =
Yet I've seen many member functions taking a string object as parameter =
without being string itself. Yet, all these functions didn't change a =
string's state. In fact they actually can't. But I know the =
StringBuilder class which is a perfect example of not using Extension =
Methods but a discrete class.


[quoted text, click to view]

Again I'd like to see a short example of how Extension Methods would to =
a trick common OOA implementation grounds don't cover gracefully.


[quoted text, click to view]

OK, we have a disagreement here. But still you will see that debugging =
Extension Methods and maintaining applications using them will become a =
big hassle. *That's* in fact the reason for avoiding to use static =
Axel Dahmen
4/3/2008 9:56:33 AM
[quoted text, click to view]

No, not at all. In my first .NET 1.0 I'd implemented an SqlHelper class =
indeed. In my second (.NET 1.1) then I've encapsulated SQL access into a =
data access layer which didn't use any static methods at all. For string =
formatting specific to data I'm dealing with I'm using separate objects, =
just as the .NET framework itself does. No, I can't remember having =
implemented a static method for a long time now.


[quoted text, click to view]
language.

Yes. I'm programming since 1977. Rest assured I know VB. But have you =
ever seen actual VB code? Have you seen anyone using OOD? I didn't. Just =
because VB offered so much procedural functionality. Just because it was =
providing classes doesn't mean people where using them.

=20
[quoted text, click to view]

Hey hey... Did you read *anything* in my previous post that said =
"VB.NET"?? I just wrote that I don't know VB.NET as I didn't use it yet. =
Of course it has the same CLR C# and J# and any other .NET language has. =
Yet it has its own extensions left. Just refer to the logical operators. =
I just don't know them all. That's what I said. Nothing more. Nothing =
less.

Regards,
Axel Dahmen
4/3/2008 9:59:09 AM
Hi Patrice,

yes, I've heard the term "syntactic sugar" a lot nowadays. Which I =
regard as "hiding loads of code behind a tiny pretty curtain".

Regards,
Axel


----------
"Patrice" <http://www.chez.com/scribe/> schrieb im Newsbeitrag =
news:uO1ZR5xkIHA.1744@TK2MSFTNGP05.phx.gbl...
[quoted text, click to view]
Axel Dahmen
4/3/2008 10:01:43 AM
[quoted text, click to view]

You are not talking about Extension Methods now anymore, are you? You =
are talking about Implicitly Typed Local Variables in C# 3.0, not =
Extension Methods. Let's not argue on these please.

Regards,
Axel Dahmen
4/3/2008 10:04:54 AM
[quoted text, click to view]

Wow, you're quick... ;)

Are we still discussing Extension Methods here? Or are we discussing =
LinQ? I'm still sure that everything Extension Methods did to LinQ could =
have been accomplished without them as gracefully.

Regards,
Axel Dahmen
4/3/2008 10:09:00 AM
[quoted text, click to view]

I've got to go to my job... Just a quick note on this: So you've =
actually *written* extensions yourself? So what's the advantage then? =
Where's the agnostic point? (This might be a stupid quick question. Just =
wanted to give it before I leave home..)

Regards,
Jon Skeet [C# MVP]
4/4/2008 9:35:27 PM
[quoted text, click to view]

But *every* time I want to use LINQ, I then have to create an instance
of MyLinq - which is adding no value to me. It's just letting me call a
bunch of methods to act on any IEnumerable<T>. Well guess what
extension methods are doing... transparently.

Adding an extra piece of inheritance without actual specialization
doesn't add any value, just complexity in my view. You're just hiding
*effectively* static methods behind instance methods.

Would you be happier if the Math class had to be instantiated each time
you used it, too?

[quoted text, click to view]

I looked at your example which copied all the data every time, instead
of streaming it. Do you have another one? Of course, it's possible to
wrap that behaviour as well, but I do think the fact that you don't
grasp the streaming and deferred nature of LINQ as being important
shows that you're not really tuned into it yet.

[quoted text, click to view]

Actually, LINQ to Objects is pretty straightforward to implement for
the most part - certainly if you don't need a particularly efficient
OrderBy algorithm, for example.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Axel Dahmen
4/4/2008 10:17:09 PM
[quoted text,