On Sat, 29 Mar 2008 15:21:53 -0700, Axel Dahmen [quoted text, click to view] <keentoknow@newsgroup.nospam> wrote: > [...] > Extension Methods in .NET is a slap in the face of all serious software > engineers.
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.
On Sat, 29 Mar 2008 18:26:18 -0700, Axel Dahmen [quoted text, click to view] <keentoknow@newsgroup.nospam> wrote: > [...] > 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?
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.
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] "Axel Dahmen" <keentoknow@newsgroup.nospam> wrote in message news:986AB0DF-FF11-4466-A9FB-682D15FA7523@microsoft.com...
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
On Sat, 29 Mar 2008 19:11:20 -0700, Axel Dahmen [quoted text, click to view] <keentoknow@newsgroup.nospam> wrote: > Thanks Peter, > > you are right. I should get more into Linq before arguing.
That's not what I wrote. [quoted text, click to view] > In fact, I'm not arguing against Linq or its syntax, but against > Extension Methods themselves.
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 quite confident that Linq could have been as gracefully been > implemented without the invention of Extension Methods.
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] > 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
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.
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > 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.
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
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
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
Hi Peter, [quoted text, click to view] > You're welcome to your opinion, even if you cannot be bothered to = express =20 > it in a polite, respectful way. Nevertheless, suffice to say your = opinion =20 > is just that: merely your opinion. Many people can and do disagree.
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] > One particular example: much of what LINQ provides would not work = without =20 > extension methods. It relies on it heavily.
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] > But regardless, no one's forcing you to use them. If you don't like = them, =20 > then don't use them.
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,
Hi Gregory, thanks for your reply as well. [quoted text, click to view] > First, extensions methods make things more elegant, as detailed by Jon = > Skeet.
Please refer to my reply to Jon. [quoted text, click to view] > If you dig deep enough, they are an "extension" of delegates, which=20 > is not a slap in the face of OO.
They are. Please refer to my reply to Peter. [quoted text, click to view] > Second, extension methods are the least kludgy way to work with = objects in=20 > LINQ. Without extensions methods, LINQ would be both verbose and = rather=20 > neutered.
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] > Used incorrectly, extension methods become a major cluster f***, but = so do=20 > most technology innovations.
I agree with you here. Everything must be used in a reasonable way. [quoted text, click to view] > Perhaps you should hold your comments until you have a firm grasp of = how=20 > they are used and why.
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] > Then, you will find that they are not so insidious=20 > after all. True, an ignorant and/or stupid developer can misuse them = and=20 > kludge things up, but a hammer can be used to cave someone's head in; = it=20 > does not make hammers stupid. Just my two cents.
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,
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] > On Sat, 29 Mar 2008 18:26:18 -0700, Axel Dahmen =20 > <keentoknow@newsgroup.nospam> wrote: >=20 >> [...] >> You got me wrong, I'm afraid. My argument is not about using them. = It's =20 >> about arguing with colleagues about using them. If I tell them to = keep =20 >> member functions within a class instead of creating some function =20 >> anywhere, providing an object as a parameter, doing nothing else than = to =20 >> handle the object's properties, what will they say? >=20 > Rather than the contrived response you attribute to them, I would = guess =20 > that they would (gently, you hope) explain to you that extension = methods =20 > are NOT a "member function" of the class being extended. >=20 > If they were, they'd have access to the class's private and protected = > members, which they don't. >=20 > Extension methods are little more than a syntactic shorthand for = writing a =20 > method that takes an instance of some class and performs some = operation =20 > using that instance, using only the public members that'd be available = to =20 > any other non-member method. People are already writing exactly that = kind =20 > of method on a regular basis. All that extension methods do is make = the =20 > code that uses that technique more concise. >=20 > As Gregory said, you would have more credibility as a detractor of =20 > extension methods if you appeared to be coming from an informed = position. =20 > Right now, you certainly don't seem to be. >=20
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > 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 = people.Where(person => person.Age > 17) > .Select(person => person.Name);
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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > > 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. > > 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?
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
Axel, [quoted text, click to view] >> 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. >Again, please refer to my reply to Jon. They are unnecessary. It would be >possible keep the pretty syntax without using them.
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] >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.
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] >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.
Wuh oh, paradigm violation, someone call the partyvan... :-D [quoted text, click to view] >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.
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
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] <keentoknow@newsgroup.nospam> wrote: > [...] >> 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. > > I agree with you here. But there is a very tiny area where they should > be used.
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.
[quoted text, click to view] >> In fact, I'm not arguing against Linq or its syntax, but against =20 >> Extension Methods themselves. >=20 > I know. And based on what you've written here, it really doesn't seem = as =20 > though you understand what extension methods do.
Believe me, I did. [quoted text, click to view] >> I'm quite confident that Linq could have been as gracefully been =20 >> implemented without the invention of Extension Methods. >=20 > I'm not convinced. Perhaps you could post a valid, complete example = of =20 > what you mean.
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] > Certainly the other example isn't nearly as graceful as =20 > using extension methods would be, given that you'd have to wrap some =20 > existing class in the generic class you seem to be proposing in order = for =20 > it to work as the code you posted shows.
I don't see a difference..... Where do you see it? [quoted text, click to view] > And if they are dealing with =20 > a class that's sealed, they cannot even sub-class the class in order = to =20 > add the method.
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] > And even if they can sub-class the class, that would =20 > require instantiating the sub-class in order to call the method on the = =20 > class.
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] > In other words, extension methods are addressing a very specific = scenario, =20 > one that is not addressable at all by the alternative you propose as =20 > superior.
Yes, a scenario like "no rules". [quoted text, click to view] > The fact is, it does not break OOP principles to have a static method = that =20 > takes as a parameter an instance of some other class and does = something =20 > with that instance. People have been writing that kind of code in OOP = =20 > languages since OOP languages have been around. And that's all that = an =20 > extension method is, except with a syntax that is more concise.
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] > For example, if you use the =20 > LINQ extension method Count() on an IEnumerable<T> instance, you need = to =20 > understand that IEnumerable<T> does not itself offer a direct access = to =20 > the count of elements, and thus there could be significant overhead to = =20 > counting an enumerable class.
So where's your point? I've added a Count() property to my above = example. [quoted text, click to view] > extension =20 > methods in some way "pretend" to be a member of another class (they = don't =20 > do any such thing...they simply use an instance of another class as = any =20 > other code not in that class could use it),
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] > that it compromises any =20 > "refacturing [sic]" effort (did you mean refactoring? in any case, it = > doesn't prevent refactoring at all),
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,
Hello Axel, [quoted text, click to view] > And if they are dealing with a class that's sealed, they cannot even > sub-class the class in order to add the method. > > That's why it's sealed. What did you think?? When someone says "Turn > right here!" are you turning left then?
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
[quoted text, click to view] >> 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? >=20 > Very, very simply: >=20 > 1) Not all actions which logically act "on" an object need to change=20 > that object's state >=20 > 2) Not all actions which are desirable in terms of appearing to act=20 > "on" an object can be anticipated by the class's original designer
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] > 3) Using inheritance to add these kinds of actions isn't always=20 > possible, and inheritance comes with many penalties in terms of = design. >=20 > Traditionally, static methods have been the way of getting round this = -=20 > I'm sure you've seen utility classes just full of methods to operate = on=20 > streams, or strings etc. Extension methods just means that when you = use=20 > the methods in those utility classes, they're available in a more=20 > transparent way.
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] > Unless you're actually debugging into the method in question, you = don't=20 > really need to know whether it was provided by the original class or = as=20 > an extension method. When you need to know, it's easy to find out -=20 > when you *don't* need to know, the more natural syntax aid's=20 > readability.
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,
Hi Alex, [quoted text, click to view] >>It would be=20 >>possible keep the pretty syntax without using them. >=20 > No, it would not be possible without some major breaking changes to = the=20 > framework. LINQ is effectively grafted *on* rather than *in* to=20 > IEnumerable, and this was only possible via extension methods. LINQ = can be=20 > cumbersome enough as it is without having to make the syntax totally=20 > unreadable by means of passing original collections into LINQ static = methods=20 > and have them return filtered IEnumerables. Generics simply wouldn't = cut it=20 > as a solution.
Please refer to my sample to to Peter here. The simple syntax is kept = without using Expansion Methods. [quoted text, click to view] > As for "implementing own Extension Methods", presumably you mean to = say that=20 > you feel MS has slapped us in the face by giving us the option of = writing=20 > methods to extend classes we don't have the source code to, and which = could=20 > potentially even be sealed? Why is that a bad thing?
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] > I've spent some time rewriting a few utility "helper" classes here and = there=20 > to be simple modules full of Extensions, and it's improved the syntax = in=20 > 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=20 > indeed as far as I'm concerned.
Could I see your SqlHelper class? I believe SqlHelper usage could be = replaced with some other solution. [quoted text, click to view] >>I perfectly agree with you. I will use them (in Linq) and I'll like = Linq=20 >>because of its usage. But I won't get to like Extension Methods >as = they=20 >>contradict OOD paradigm of keeping an obvious member function within = the=20 >>class itself. >=20 > Wuh oh, paradigm violation, someone call the partyvan... :-D
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] > If you genuinely believe Generics alone could have been used to = implement=20 > LINQ with identical syntax, I suspect you still don't fully understand = what=20 > Extension methods do and are for.
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] > As for multiple inheritance, I would=20 > strongly question as to whether that does truly conform to OOD in this = day=20 > and age. Multi-inheritance creates a dizzying array of new problems = to be=20 > solved, and again doesn't create the same elegant syntax of extension=20 > methods.
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] > Perhaps you could explain how you think either Generics or = Multi-Inheritance=20 > could be used to mimic the current syntax of LINQ without breaking=20 > compatibility?
Please refer to the sample I've given to Peter in my last post. [quoted text, click to view] > ...and now your IEnumerable is actually of type Linq rather than List, = which=20 > will impact your code if you're passing that as a parameter anywhere =
else. No.. The Linq class could be derived from, e.g., List and could be used = anywhere. [quoted text, click to view] > Multiple inheritance? Presumably you'd then have (for example) a = List<T>=20 > class in the framework that inherited from its regular base class,=20 > implemented IEnumerable, *and* inherited from a Linq base class? But = then=20 > it's no longer strictly the same type as the v2.0 List<T> class, so = you=20 > break masses of code.
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] > Remember that .NET 3.5 is essentially v2.0 with bolt ons, one of which = is=20 > LINQ. It still has to be backwards compatible. I can see how = extension=20 > methods were born of necessity for the purposes of injecting LINQ into = the=20 > framework in a non-breaking manner, and some might call it a kludge, = but=20 > it's one I welcome with open arms.
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] > There's a lot of weird, badly implemented and overly cryptic crap in = ..NET=20 > 3.5 --- things I think we could have done without, things that are = heading=20 > in the wrong direction, things that are just down right not finished = yet and=20 > shouldn't have been released. LINQ and all its many = framework-enhancing=20 > children however is not on that list. In my opinion, anyway ;-)
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,
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > >> 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? > > > > 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 > > 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.
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] > Regarding 2): In fact, they *can't*. That's what inheritance is made for.
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] > > 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. > > I fully agree with you. That's the purpose of Expansion Methods.
Extension methods, not expansion methods. [quoted text, click to view] > 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.
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] > 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. > > > 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. > > 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).
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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote:
<snip> [quoted text, click to view] > > ...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. > > No.. The Linq class could be derived from, e.g., List and could be > used anywhere.
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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > >> In fact, I'm not arguing against Linq or its syntax, but against > >> Extension Methods themselves. > > > > I know. And based on what you've written here, it really doesn't seem as > > though you understand what extension methods do. > > Believe me, I did. > > > >> I'm quite confident that Linq could have been as gracefully been > >> implemented without the invention of Extension Methods. > > > > I'm not convinced. Perhaps you could post a valid, complete example of > > what you mean. > > 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:
<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
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 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.
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] > One particular example: much of what LINQ provides would not work without > extension methods. It relies on it heavily.
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] > But regardless, no one's forcing you to use them. If you don't like them, > then don't use them.
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
[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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > > 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. > > 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.
They are *fundamentally* different from LINQ. [quoted text, click to view] > Again, Linq is no magic. Extension Methods makes it look magic, but > it isn't.
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
Hi Rory, [quoted text, click to view] > IMHO... Sealing a class has less to do with stopping you inheriting = from=20 > it and more to do with ensuring that someone doesn't fundamentally = alter=20 > the way it works and breaking methods that depend on params of that = type. >=20 > For example if you could inherit from string you would be able to = create=20 > a derived string that fundamentally broke the internasl of it and = would still=20 > be passable to methods that required a string.
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() {}
[quoted text, click to view] > someData.Where(firstCondition) > .Where(secondCondition) > .OrderBy(firstOrdering) > .ThenBy(secondOrdering) > .Select(projection) >=20 > then I only want one item of data to be copied at a time. Your=20 > implementation breaks that completely.
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.
[quoted text, click to view] >>> The fact is, it does not break OOP principles to have a static = method =20 >>> 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. >> >> I agree with you here. But there is a very tiny area where they = should =20 >> be used. >=20 > No one has suggested extension methods be used except in the very = specific =20 > scenario I describe above. They in fact CANNOT BE USED IN ANY OTHER =20 > SCENARIO. And you have specifically written here that in that = scenario -- =20 > THE ONLY ONE IN WHICH EXTENSION METHODS CAN BE USED -- you agree with = me. =20 > So what's your problem?
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!
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > > 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 > > You are right. I'd even go further: I'd say that doing *anything* > unnecessarily is undesirable in many situations. ;)
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] > > 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 > > 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. 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] > >> Regarding 2): In fact, they *can't*. That's what inheritance is made for. > > > > No - inheritance is made for *specializing* behaviour, not representing > > other behaviour which is still appropriate to *every* instance of the > > base type. > > 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.
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] > >> I fully agree with you. That's the purpose of Expansion Methods. > > > > Extension methods, not expansion methods. > > Yep, right. Got to hurry over the keys sometimes... Yet, where's the > difference?
One is a technically correct term, the other isn't. [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. > > 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.
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] > > 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. > > 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.
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] > > 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. > > 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 methods.
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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > > For example, Marc > > Gravell and I recently wrote a "push" version of LINQ by > > implementing > > the same set of operators as extensions on a different interface. > > 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?
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] > Where's the agnostic point? (This might be a stupid quick question. > Just wanted to give it before I leave home..)
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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > >> No.. The Linq class could be derived from, e.g., List and could be > >> used anywhere. > > > > 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. > > You are not talking about Extension Methods now anymore, are you?
Um, yes. [quoted text, click to view] > You are talking about Implicitly Typed Local Variables in C# 3.0, not > Extension Methods. Let's not argue on these please.
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
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > > What would happen if you passed an infinite sequence into that? LINQ > > would handle it absolutely fine. Your code wouldn't. > > 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.
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
[quoted text, click to view] > Using inheritance unnecessarily to add functionality is: >=20 > a) impossible in many situations (e.g. when the class is sealed) > b) undesirable in many other situations
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] > Personally I prefer most classes to be sealed - there is a design cost = > to inheritance, which should not be overlooked. See >=20 > http://msmvps.com/jon.skeet/archive/2006/03/04/inheritancetax.aspx 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] >> Regarding 2): In fact, they *can't*. That's what inheritance is made = for. >=20 > No - inheritance is made for *specializing* behaviour, not = representing=20 > other behaviour which is still appropriate to *every* instance of the=20 > base type.
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] >> I fully agree with you. That's the purpose of Expansion Methods. >=20 > Extension methods, not expansion methods.
Yep, right. Got to hurry over the keys sometimes... Yet, where's the = difference? [quoted text, click to view] > Two examples in my own experience: >=20 > 1) String utility routines. We can't derive from string, nor could we=20 > force every instance of string returned by the library methods to be = an=20 > instance of our own string type even if we could. Where, then, would=20 > you write utility methods for strings? Such methods are *very* common.
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] > 2) Stream routines, e.g. to read the whole of a stream into a byte=20 > array, or copy the contents of one stream to another. These are very=20 > commonly mis-implemented operations, so it's good to have them in one=20 > place. They can operate on *any* stream, so inheritance is=20 > inappropriate. Static method taking a stream is entirely consistent=20 > with this situation - and extension methods make them easier to use.
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] > Okay, so really you want to virtually abolish static methods. Sorry,=20 > can't agree there. I rather like being able to use LINQ operations on=20 > *any* IEnumerable<T> rather than having to construct an instance of=20 > MyLinq<T> every time. It sounds like you want to force people to=20 > artificially create an instance of a type for *no reason* other than = to=20 > avoid using static methods. >=20 > I don't think that's a pragmatic or sensible approach.
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 =
[quoted text, click to view] > So you've honestly never used static methods for anything? No static = class=20 > containing methods to handle, say, string-formatting specific to the = data=20 > 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=20 > not just a case of "I put them all into a formatting class which I=20 > instantiate and call the methods of as needed"...
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] > I think this is indicative of you not understanding the framework. VB = has=20 > existed for much, much longer than C# and had the beginnings of OOD as = of=20 > version 4 (mid 90s?) when MS first introduced classes into the =
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] > When .NET was released, C# and VB.NET were released at the same time. = Both=20 > support an identical set of OOD tools. VB.NET is no more or less = procedural=20 > than C#, it's just a different syntax of what is essentially the same=20 > language under the hood. OOD is no newer in VB.NET than it is in C#, = and=20 > arguably it's existed in VB for longer due to VB's age.
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,
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] > Also keep in mind anyway that they are pretty much nothing more than=20 > syntactic sugar... >=20 > This is basically another notation for MyHelpMethod(MyInstance) so = that you=20 > can write MyInstance.MyHelpMethod instead... >=20 > -- > Patrice >=20 > "Axel Dahmen" <keentoknow@newsgroup.nospam> a =E9crit dans le message = de news:=20 > 6CB34136-A7A9-481C-98FE-8A938D39A20D@microsoft.com... > Hi Peter, >=20 >> 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. >=20 > You're right. It's not one of my strengths to be eloquent when I see a = bad=20 > design decision. I apologize for that. I'd like to hear opinions of = those=20 > who disagree. Particularly how they want to explain Extension Methods = in OOD=20 > terms. How can someone possibly argue about keeping an objects methods = > within the object (a typical OOD pattern) while at the same time = accepting=20 > Extension Methods? >=20 >=20 >> One particular example: much of what LINQ provides would not work = without >> extension methods. It relies on it heavily. >=20 > I guess so. That's just why they invented it. There's not other = possible=20 > reason for it that I could think of... Still it's a wrong approach. = The same=20 > Linq syntax could have been achieved with other, more OOD, practices. >=20 >=20 >> But regardless, no one's forcing you to use them. If you don't like = them, >> then don't use them. >=20 > You got me wrong, I'm afraid. My argument is not about using them. = It's=20 > about arguing with colleagues about using them. If I tell them to keep = > member functions within a class instead of creating some function = anywhere,=20 > providing an object as a parameter, doing nothing else than to handle = the=20 > object's properties, what will they say? "Must be a valid pattern. MS = and=20 > millions of others are using it!" How am I (or any other Software = Engineer)=20 > supposed to argument on this? >=20 > Regards, > Axel Dahmen=20 >=20
[quoted text, click to view] >> No.. The Linq class could be derived from, e.g., List and could be >> used anywhere. >=20 > But *then* it's restricted to Lists - what happens if I've got an = array=20 > instead? And if the Linq class were to derive from List, you'd have a=20 > *really* broken inheritance chain.
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,
[quoted text, click to view] > What would happen if you passed an infinite sequence into that? LINQ=20 > would handle it absolutely fine. Your code wouldn't.
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,
[quoted text, click to view] > For example, Marc=20 > Gravell and I recently wrote a "push" version of LINQ by implementing=20 > the same set of operators as extensions on a different interface.
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,
[quoted text, click to view] Axel Dahmen <keentoknow@newsgroup.nospam> wrote: > > 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. > > Frankly, I don't see a difference to my example, where you just would had to write: > > myLinq.Where(x => x.Length > 5) > .Select(x.ToUpper()) > > No IEnumerable<T> extension, no wrapper class. Just a new kind of > collection class (MyLinq).
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] > Did you have a chance to look at my > example?
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] > Of course, I didn't implement delegates as method > parameters. I was just a quick example. But implementing that would > be an easy exercise. And it would have been done my MS, not us.
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
|