Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Extension Methods - Satan's favourite construct (controversial to nerds)

Extension Methods - Satan's favourite construct (controversial to nerds)

Scheduled Pinned Locked Moved The Lounge
csharpfunctionallinqbusinessregex
94 Posts 34 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Rob Philpott
    wrote on last edited by
    #1

    Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

    Regards, Rob Philpott.

    L N E M R 24 Replies Last reply
    0
    • R Rob Philpott

      Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

      Regards, Rob Philpott.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      Yes. Oh yes. I like extension methods for 1 thing: enums. But only because they can't contain any methods themselves, which would have been a better (and more obvious) solution.

      1 Reply Last reply
      0
      • R Rob Philpott

        Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

        Regards, Rob Philpott.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        Rob Philpott wrote:

        A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly.

        Hmmm... I'll just say, it seems you are doing it wrong then. I use extension methods, but only to the point where it is obvious and could easily be added by re-inventing the wheel right then and there on the spot. For example, I often use IEnumerable<T> but prefer many of the Extensions offered by LINQ when using IList. Not too difficult to make myself.

        public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
        {
        foreach (var item in collection)
        {
        action(item);
        }
        }

        I package it up and call it a done deal and use it. Now if a developer can not figure out what SomeRandomCollection.ForEach(item => {//Do stuff}); means then I do not want them working in my code base anyways. Granted extensions can and will be abused. But that is true of any feature.

        Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

        R J J 3 Replies Last reply
        0
        • R Rob Philpott

          Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

          Regards, Rob Philpott.

          N Offline
          N Offline
          Nagy Vilmos
          wrote on last edited by
          #4

          Maybe, just maybe, it's not the structure itself that is at fault but the whore-coders who don't know what they're doing that is causing your prolapsed brain.

          Reality is an illusion caused by a lack of alcohol

          R 1 Reply Last reply
          0
          • N Nagy Vilmos

            Maybe, just maybe, it's not the structure itself that is at fault but the whore-coders who don't know what they're doing that is causing your prolapsed brain.

            Reality is an illusion caused by a lack of alcohol

            R Offline
            R Offline
            Rob Philpott
            wrote on last edited by
            #5

            Certainly so, but that's a bit like handing out guns and telling everyone that people kill, not guns. And in the computer world, you have to accept there are a lot of ego-maniacs who love to do things a clever way rather than a straight-forward way because they think it makes them 'uber-coders'. That is one of the main problems in the industry.

            Regards, Rob Philpott.

            N 1 Reply Last reply
            0
            • R Rob Philpott

              Certainly so, but that's a bit like handing out guns and telling everyone that people kill, not guns. And in the computer world, you have to accept there are a lot of ego-maniacs who love to do things a clever way rather than a straight-forward way because they think it makes them 'uber-coders'. That is one of the main problems in the industry.

              Regards, Rob Philpott.

              N Offline
              N Offline
              Nagy Vilmos
              wrote on last edited by
              #6

              If the reason for doing something in a non-conventional way is 'because I can' then that doesn't make them a ubercoder. It makes them a cun...

              Reality is an illusion caused by a lack of alcohol

              1 Reply Last reply
              0
              • L Lost User

                Rob Philpott wrote:

                A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly.

                Hmmm... I'll just say, it seems you are doing it wrong then. I use extension methods, but only to the point where it is obvious and could easily be added by re-inventing the wheel right then and there on the spot. For example, I often use IEnumerable<T> but prefer many of the Extensions offered by LINQ when using IList. Not too difficult to make myself.

                public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
                {
                foreach (var item in collection)
                {
                action(item);
                }
                }

                I package it up and call it a done deal and use it. Now if a developer can not figure out what SomeRandomCollection.ForEach(item => {//Do stuff}); means then I do not want them working in my code base anyways. Granted extensions can and will be abused. But that is true of any feature.

                Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                R Offline
                R Offline
                Rob Philpott
                wrote on last edited by
                #7

                You see, without entering into an argument I see no benefit in the piece of code you show above. All you've done is got rid of a couple of lines of clear explicit code which guarantees that people can see what it does and what it does not do. What happens if an exception is thrown during iteration? You can't tell - depends on what the extension method does.

                Regards, Rob Philpott.

                L R 2 Replies Last reply
                0
                • R Rob Philpott

                  Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

                  Regards, Rob Philpott.

                  E Offline
                  E Offline
                  Ennis Ray Lynch Jr
                  wrote on last edited by
                  #8

                  Of sealed classes : ) I mean, really, why must I constantly check for DB Null when reading from a db. Just make it real null instead.

                  Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost "All users always want Excel" --Ennis Lynch

                  R 1 Reply Last reply
                  0
                  • R Rob Philpott

                    Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

                    Regards, Rob Philpott.

                    M Offline
                    M Offline
                    Marc Clifton
                    wrote on last edited by
                    #9

                    What, you don't like this code?

                    // Menu copy handler. If a control has focus and its an edit box, copy its text to the clipboard,
                    // otherwise if there's an active notecard instance, tell the notecard's view to do the copy to the clipboard.
                    protected void Copy(object sender, EventArgs args)
                    {
                    Program.GetFocusedControl().IfNotNull(ctrl =>
                    {
                    ctrl.Is(tb => tb.Copy());
                    }).Else(() => ActiveDocumentController.IfNotNull(notecard => notecard.NotecardView.Copy()));
                    }

                    ;P Marc

                    Latest Article: C# and Ruby Classes: A Deep Dive
                    My Blog

                    R N G 3 Replies Last reply
                    0
                    • R Rob Philpott

                      You see, without entering into an argument I see no benefit in the piece of code you show above. All you've done is got rid of a couple of lines of clear explicit code which guarantees that people can see what it does and what it does not do. What happens if an exception is thrown during iteration? You can't tell - depends on what the extension method does.

                      Regards, Rob Philpott.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Rob Philpott wrote:

                      I see no benefit in the piece of code you show above.

                      It may just be my opinion but I find this

                      collection.ForEach(item =>
                      {
                      //DoStuff
                      });

                      more readable than

                      foreach(var item in collection)
                      {
                      //DoStuff
                      }

                      or

                      foreach(SomeDependentObject item in collection)
                      {
                      //DoStuff
                      }

                      or

                      for(int i = 0; i < collection.Count(); i++)
                      {
                      //DoStuff
                      }

                      and so on and so forth. It seems more natural when I am coding. I am given the context (the collection) and then I run some action on it for each item.

                      Rob Philpott wrote:

                      What happens if an exception is thrown during iteration?

                      Well then an exception happens as it would with any of the iteration styles above.

                      Rob Philpott wrote:

                      You can't tell - depends on what the extension method does.

                      This is my point. If your extension is complicated and verbose you are doing it wrong. It should be simple and highly intuitive of what it is doing and any exceptions that are being passed in to the extension should not be captured by the extension but show up where the exception actually occurred. This is the nature of static class and has nothing to do with extensions other than that is how you implement extensions.

                      Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                      R B J 3 Replies Last reply
                      0
                      • E Ennis Ray Lynch Jr

                        Of sealed classes : ) I mean, really, why must I constantly check for DB Null when reading from a db. Just make it real null instead.

                        Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost "All users always want Excel" --Ennis Lynch

                        R Offline
                        R Offline
                        Rob Philpott
                        wrote on last edited by
                        #11

                        Not quite with you, but on that note, if a quantity can have a DB Null its likely going to be a reference type or Nullable<> in which you can just do (reader[i] as int?) (reader["name"] as string) etc, and that will turn you DB nulls to .net nulls for you. If you use extensions here - why not. I use them on String to give me a traditional Left and Right function. I think it's when you start involving them in the system architecture that things start to do horribly wrong.

                        Regards, Rob Philpott.

                        E S 2 Replies Last reply
                        0
                        • M Marc Clifton

                          What, you don't like this code?

                          // Menu copy handler. If a control has focus and its an edit box, copy its text to the clipboard,
                          // otherwise if there's an active notecard instance, tell the notecard's view to do the copy to the clipboard.
                          protected void Copy(object sender, EventArgs args)
                          {
                          Program.GetFocusedControl().IfNotNull(ctrl =>
                          {
                          ctrl.Is(tb => tb.Copy());
                          }).Else(() => ActiveDocumentController.IfNotNull(notecard => notecard.NotecardView.Copy()));
                          }

                          ;P Marc

                          Latest Article: C# and Ruby Classes: A Deep Dive
                          My Blog

                          R Offline
                          R Offline
                          Rob Philpott
                          wrote on last edited by
                          #12

                          Ah, you were my predecessor! Frankly no, I really don't.

                          Regards, Rob Philpott.

                          1 Reply Last reply
                          0
                          • L Lost User

                            Rob Philpott wrote:

                            I see no benefit in the piece of code you show above.

                            It may just be my opinion but I find this

                            collection.ForEach(item =>
                            {
                            //DoStuff
                            });

                            more readable than

                            foreach(var item in collection)
                            {
                            //DoStuff
                            }

                            or

                            foreach(SomeDependentObject item in collection)
                            {
                            //DoStuff
                            }

                            or

                            for(int i = 0; i < collection.Count(); i++)
                            {
                            //DoStuff
                            }

                            and so on and so forth. It seems more natural when I am coding. I am given the context (the collection) and then I run some action on it for each item.

                            Rob Philpott wrote:

                            What happens if an exception is thrown during iteration?

                            Well then an exception happens as it would with any of the iteration styles above.

                            Rob Philpott wrote:

                            You can't tell - depends on what the extension method does.

                            This is my point. If your extension is complicated and verbose you are doing it wrong. It should be simple and highly intuitive of what it is doing and any exceptions that are being passed in to the extension should not be captured by the extension but show up where the exception actually occurred. This is the nature of static class and has nothing to do with extensions other than that is how you implement extensions.

                            Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                            R Offline
                            R Offline
                            Rob Philpott
                            wrote on last edited by
                            #13

                            Yeah, I can accept that as a question of style and preference. For me, the implicit assumption that the extension method isn't (and shouldn't) be doing anything special at all negates the need for it, but for those who prefer the more 'fluent' style of coding I take your point.

                            Regards, Rob Philpott.

                            1 Reply Last reply
                            0
                            • M Marc Clifton

                              What, you don't like this code?

                              // Menu copy handler. If a control has focus and its an edit box, copy its text to the clipboard,
                              // otherwise if there's an active notecard instance, tell the notecard's view to do the copy to the clipboard.
                              protected void Copy(object sender, EventArgs args)
                              {
                              Program.GetFocusedControl().IfNotNull(ctrl =>
                              {
                              ctrl.Is(tb => tb.Copy());
                              }).Else(() => ActiveDocumentController.IfNotNull(notecard => notecard.NotecardView.Copy()));
                              }

                              ;P Marc

                              Latest Article: C# and Ruby Classes: A Deep Dive
                              My Blog

                              N Offline
                              N Offline
                              Nagy Vilmos
                              wrote on last edited by
                              #14

                              Marc, you truly are an evil man. Well done!

                              Reality is an illusion caused by a lack of alcohol

                              1 Reply Last reply
                              0
                              • R Rob Philpott

                                Not quite with you, but on that note, if a quantity can have a DB Null its likely going to be a reference type or Nullable<> in which you can just do (reader[i] as int?) (reader["name"] as string) etc, and that will turn you DB nulls to .net nulls for you. If you use extensions here - why not. I use them on String to give me a traditional Left and Right function. I think it's when you start involving them in the system architecture that things start to do horribly wrong.

                                Regards, Rob Philpott.

                                E Offline
                                E Offline
                                Ennis Ray Lynch Jr
                                wrote on last edited by
                                #15

                                I am completely opposed to the AS operator. It causes more problems than it is worth. You talk about sloppy programming with extension methods, ugh, AS is worse. In fact, the AS keyword brought down an entire production system. (combined with a lazy programmer) The short story is that instead of relying on strong typing from the DB the developer used AS and converted the type to the expected type. Some DBA decided to change a database type without telling any one and a few weeks later another subsystem broke because of invalid data. Had the type been formally cast this error would have been caught immediately. I am of the camp that strong typing is important. Using conversion ... everywhere as AS encourages, only serves to disassociate developers from types (ok, this includes var) and types and the knowledge thereof is a fundamental underpinning of a stable, large system.

                                Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost "All users always want Excel" --Ennis Lynch

                                R B J pkfoxP B 6 Replies Last reply
                                0
                                • E Ennis Ray Lynch Jr

                                  I am completely opposed to the AS operator. It causes more problems than it is worth. You talk about sloppy programming with extension methods, ugh, AS is worse. In fact, the AS keyword brought down an entire production system. (combined with a lazy programmer) The short story is that instead of relying on strong typing from the DB the developer used AS and converted the type to the expected type. Some DBA decided to change a database type without telling any one and a few weeks later another subsystem broke because of invalid data. Had the type been formally cast this error would have been caught immediately. I am of the camp that strong typing is important. Using conversion ... everywhere as AS encourages, only serves to disassociate developers from types (ok, this includes var) and types and the knowledge thereof is a fundamental underpinning of a stable, large system.

                                  Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost "All users always want Excel" --Ennis Lynch

                                  R Offline
                                  R Offline
                                  Rob Philpott
                                  wrote on last edited by
                                  #16

                                  While I'm with you about typing (I'm of age where you were brought up to respect type safety) I don't see an issue with using 'as'. I often see a condition checking if something 'is' a type followed by an explicit cast, and I tend to replace the 'is' with an 'as' and use a null check - one less cast in effect. Actually, it's not extension methods or 'as' which is the real horror. Its 'var', but we'll leave that for another day. :)

                                  Regards, Rob Philpott.

                                  D 1 Reply Last reply
                                  0
                                  • R Rob Philpott

                                    Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

                                    Regards, Rob Philpott.

                                    R Offline
                                    R Offline
                                    Rama Krishna Vavilala
                                    wrote on last edited by
                                    #17

                                    Not really! They are extremely useful for interfaces especially and in those cases where the code is not really in your hand.

                                    Rob Philpott wrote:

                                    the way to build a good system is to always, always, always keep everything as simple as you can make it.

                                    And extension methods can be used as a way to keep the code simple and non-repetitive. In fact you nailed it well. Keep the end code simple - minimize complexities and I do not see extension methods being a hurdle rather it can be a tool to do so.

                                    J 1 Reply Last reply
                                    0
                                    • L Lost User

                                      Rob Philpott wrote:

                                      I see no benefit in the piece of code you show above.

                                      It may just be my opinion but I find this

                                      collection.ForEach(item =>
                                      {
                                      //DoStuff
                                      });

                                      more readable than

                                      foreach(var item in collection)
                                      {
                                      //DoStuff
                                      }

                                      or

                                      foreach(SomeDependentObject item in collection)
                                      {
                                      //DoStuff
                                      }

                                      or

                                      for(int i = 0; i < collection.Count(); i++)
                                      {
                                      //DoStuff
                                      }

                                      and so on and so forth. It seems more natural when I am coding. I am given the context (the collection) and then I run some action on it for each item.

                                      Rob Philpott wrote:

                                      What happens if an exception is thrown during iteration?

                                      Well then an exception happens as it would with any of the iteration styles above.

                                      Rob Philpott wrote:

                                      You can't tell - depends on what the extension method does.

                                      This is my point. If your extension is complicated and verbose you are doing it wrong. It should be simple and highly intuitive of what it is doing and any exceptions that are being passed in to the extension should not be captured by the extension but show up where the exception actually occurred. This is the nature of static class and has nothing to do with extensions other than that is how you implement extensions.

                                      Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                                      B Offline
                                      B Offline
                                      BobJanova
                                      wrote on last edited by
                                      #18

                                      But what about CollectionUtils.ForEach(collection, item => { ... })? It's the hiding of the actual location of the code that really gets me about extension methods, and it doesn't gain enough over that snippet to be worth the opacity, imo.

                                      L 1 Reply Last reply
                                      0
                                      • R Rob Philpott

                                        Sometimes I yearn for a return to .NET 2.0. The C# that came with it was a great language and now that generics were included it was essentially complete in my mind. Since then, they've been adding all sorts of dubious things to the language LINQ being the most notable but now we also have the async/await business which really is anything but the simple solution to asynchronous programming they tell us it is. Extensions methods, everyone's favourite encapsulation anti-pattern debuted with LINQ in order to make it work and some people (me) viewed them with suspicious eyes at the time but didn't really know how bad things could get. Having recently worked on a system where they have been abused to the fullest I can tell you. You start off with pretty hollow objects with very little in the way of methods, just enough to get at the data. Then, you put all your logic in extension methods, preferably in different assemblies. A sort of warped onion architecture. Now, any normal developer who goes looking for a type's methods won't find them in the type or even that assembly. A missing reference will make them disappear completely. Also, with careful planning, you can make it exceedingly hard to move that logic back where it belongs because doing so will cause all kinds of circular dependency issues. Immutable code! Shocking stuff, but if you really hate the world, don't forget the Action<> and Func<> delegates. These are useful because you can avoid passing meaningful data to methods. Instead just pass delegates everywhere (a functional programming approach I'm told). This makes it practically impossible for anyone to work out the execution flow by examining the code. Combine the two and you have one thoroughly malevolent system. People bang on about patterns all the time in software development, but if you ask me (I'm aware you didn't) the way to build a good system is to always, always, always keep everything as simple as you can make it.

                                        Regards, Rob Philpott.

                                        L Offline
                                        L Offline
                                        Lost User
                                        wrote on last edited by
                                        #19

                                        I couldn't resist upvoting your post. Frankly, I feel irritated at times when I have to work with these "advanced" features.

                                        1 Reply Last reply
                                        0
                                        • E Ennis Ray Lynch Jr

                                          I am completely opposed to the AS operator. It causes more problems than it is worth. You talk about sloppy programming with extension methods, ugh, AS is worse. In fact, the AS keyword brought down an entire production system. (combined with a lazy programmer) The short story is that instead of relying on strong typing from the DB the developer used AS and converted the type to the expected type. Some DBA decided to change a database type without telling any one and a few weeks later another subsystem broke because of invalid data. Had the type been formally cast this error would have been caught immediately. I am of the camp that strong typing is important. Using conversion ... everywhere as AS encourages, only serves to disassociate developers from types (ok, this includes var) and types and the knowledge thereof is a fundamental underpinning of a stable, large system.

                                          Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost "All users always want Excel" --Ennis Lynch

                                          B Offline
                                          B Offline
                                          BobJanova
                                          wrote on last edited by
                                          #20

                                          as is excellent in a situation where you don't know what you have, but you might want to do something with it. It saves you the double type check, of

                                          if(x is MyType){
                                          MyType myX = (MyType)x;
                                          myX.whatever;
                                          }

                                          instead you have

                                          MyType myX = x as MyType;
                                          if(myX != null){
                                          myX.whatever;
                                          }

                                          ... which is the same length but more efficient and (imo) more obvious. When you have known types on both sides and known supposed matchups then it is just the wrong tool for the job. It's not the sledgehammer's fault it isn't good at painting windows.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups