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. Other Discussions
  3. Clever Code
  4. Methods within methods

Methods within methods

Scheduled Pinned Locked Moved Clever Code
cssquestion
12 Posts 10 Posters 8 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.
  • A Ashish Kaila

    I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

    Ashish Kaila

    P Offline
    P Offline
    PIEBALDconsult
    wrote on last edited by
    #2

    Yeeahh... anonymous methods? They can be a bit useful at times.

    1 Reply Last reply
    0
    • A Ashish Kaila

      I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

      Ashish Kaila

      S Offline
      S Offline
      Shahriar Iqbal Chowdhury Galib
      wrote on last edited by
      #3

      what will be use?

      1 Reply Last reply
      0
      • A Ashish Kaila

        I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

        Ashish Kaila

        F Offline
        F Offline
        Fernando A Gomez F
        wrote on last edited by
        #4

        It kinda reminded me of local classes in C++, where you could create a class within a method (with certain restrictions). I always wondered how could they be used, until I read Alexandrescu's Modern C++ Design, where he pointed a particular use: create a class that implements certain interface, so you could have a factory-like method...

        M P 2 Replies Last reply
        0
        • F Fernando A Gomez F

          It kinda reminded me of local classes in C++, where you could create a class within a method (with certain restrictions). I always wondered how could they be used, until I read Alexandrescu's Modern C++ Design, where he pointed a particular use: create a class that implements certain interface, so you could have a factory-like method...

          M Offline
          M Offline
          Mike Winiberg
          wrote on last edited by
          #5

          It's amazing how techniques etc that have been around for many, many years keep cropping up as though they were new - Pascal anyone? 8)

          U 1 Reply Last reply
          0
          • A Ashish Kaila

            I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

            Ashish Kaila

            A Offline
            A Offline
            Adriaan Davel
            wrote on last edited by
            #6

            The best thing about anonymous methods IMO is that you can pass them as parameters, which gives a couple of Async pattern options...

            ____________________________________________________________ Be brave little warrior, be VERY brave

            1 Reply Last reply
            0
            • M Mike Winiberg

              It's amazing how techniques etc that have been around for many, many years keep cropping up as though they were new - Pascal anyone? 8)

              U Offline
              U Offline
              User 4223959
              wrote on last edited by
              #7

              I agree, there are times I miss those things, though barely remember how many years ago I saw Pascal for the last time. BTW, you can do the same tricks with anonymous inner classes, in Java...

              1 Reply Last reply
              0
              • A Ashish Kaila

                I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

                Ashish Kaila

                P Offline
                P Offline
                Paul Michalik
                wrote on last edited by
                #8

                A shorter version which demonstrates the locality better is this:

                void PrintElements(Grid grid, bool isVertical)
                {
                foreach (FrameworkElement element in grid.Children) {
                Console.WriteLine(arg => isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg));
                }
                }

                However, you might not know that this locality is just an illusion generated by the C# compiler, or more precisely by it's code generation features. In reality the containing class is extended by automatically generated code elements which represent the lambda (and the environment of it, if necessary). All of these elements are added to assembly's meta-data (so that they do consume memory if assembly is loaded...) For your example the compiler would add a new anonymous internal class which represents the closure of the lambda environment. The generated code would look something like this (assuming your class was named YourClass and the compiler decided to choose some unique names XX and xx):

                class YourClass {

                \[CompilerGenerated\]
                private sealed class <>XX : public System.Object {
                    public bool isVertical;
                    
                    public <>XX() {}
                
                    int <PrintElements>\_xx(int arg) {
                        return IsVetical ? Grid.GetRow(arg) : Grid.GetRow(arg);
                    }
                }
                
                void PrintElements(Grid grid, bool isVertical)
                {
                    // compiler generated ->
                    class <>XX xx1 = new <>XX();
                    xx1.IsVertical = isVertical; 
                    System.Function<bool, int> xx2 = null;
                    // <- compiler generated
                
                    foreach (FrameworkElement element in grid.Children) {
                        // compiler generated ->
                        if (xx2 != null) {
                            xx2 = new System.Function<bool, int>(xx1.<PrintElements>\_xx);
                        }
                        Console.WriteLine(xx2);
                        //<-compiler generated
                    }
                }
                

                }

                The compiler possesses a lot of intelligence on deciding what code is going to be generated, in your example a local isValid identifier is required so it would generate the local closure class. If no closures are required, it just adds methods (or static methods) to the containing class depending on whether you are using class instance members or not. Interesting, isn't it? Cheers, Paul

                1 Reply Last reply
                0
                • F Fernando A Gomez F

                  It kinda reminded me of local classes in C++, where you could create a class within a method (with certain restrictions). I always wondered how could they be used, until I read Alexandrescu's Modern C++ Design, where he pointed a particular use: create a class that implements certain interface, so you could have a factory-like method...

                  P Offline
                  P Offline
                  Paul Michalik
                  wrote on last edited by
                  #9

                  Well, this is not allowed in C#, you cannot define classes (or structs) at method scope. However, it'd interesting to know, how the compiler translates the c++0x lambdas. The appropriate definitions in the current standard draft occupy 5 1/2 pages and, as usual, are not clear after first reading... The example from the orginal post would look like this (assuming some hypotetical framework grid_t which defines static methods get_row and get_col and delivers a sequence of children):

                  void PrintElements(const grid_t& grid, bool isVertical) {
                  std::transform(grid.children().cbegin(), grid.children().cend(),
                  std::output_iterator<int>(std::cout), [isVertical](int arg) -> int {
                  isVertical ? grid_t::get_row(arg) : grid_t::get_col(arg);
                  });
                  }

                  Cheers, Paul Edit: As far as I understand what the standard says, the result might look like below (it'd be interesting to see how the code really translates with more complex closures taking environment variables by reference etc...):

                  void PrintElements(const grid_t& grid, bool isVertical) {
                  struct XX {
                  bool xx_IsVertical;
                  int operator(int arg) {
                  xx_IsVertical ? grid_t::get_row(arg) : grid_t::get_col(arg);
                  }

                      XX(bool \_xx) : xx\_IsVertical(\_xx) {};
                  };
                  std::transform(grid.children().cbegin(), grid.children().cend(),
                      std::output\_iterator<int>(std::cout), XX(isVertical));
                  

                  }

                  modified on Sunday, November 28, 2010 7:25 AM

                  1 Reply Last reply
                  0
                  • A Ashish Kaila

                    I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

                    Ashish Kaila

                    R Offline
                    R Offline
                    RobCroll
                    wrote on last edited by
                    #10

                    Anonymous methods do have there place but I question there use in most cases. To me they breach basic OOP rules and make code less readable and therefore less maintainable.

                    1 Reply Last reply
                    0
                    • A Ashish Kaila

                      I just discovered how powerful concept is to have a method local to another method. For instance let's assume you have a function that lists the position of elements within a grid. For the sake of simplicity imagine a grid can only have either rows or columns (but not both). Here is what you can do: void PrintElements(Grid grid, bool isVertical) { Func getElementPosition = arg=> isVertical ? Grid.GetRow(arg) : Grid.GetColumn(arg); foreach (FrameworkElement element in grid.Children) { Console.WriteLine(getElementPosition(element)); } } Hence a local func is only visible within PrintElements and can be used in numerous occasions !

                      Ashish Kaila

                      M Offline
                      M Offline
                      mbue
                      wrote on last edited by
                      #11

                      void SortUI(unsigned int* array,const unsigned int count) { typedef struct{ static int cmp(const void *a, const void *b){ return *(int*)a-*(int*)b; } }_; qsort(array,count,sizeof(unsigned int),_::cmp); } void SortSTR(TCHAR** array,const unsigned int count) { typedef struct{ static int cmp(const void *a, const void *b){ return _tcscmp(*(TCHAR**)a,*(TCHAR**)b); } }_; qsort(array,count,sizeof(TCHAR*),_::cmp); } void SortDF(double* array,const unsigned int count) { typedef struct{ static int cmp(const void *a, const void *b){ return *(double*)a<*(double*)b?-1:(*(double*)a>*(double*)b?+1:0); } }_; qsort(array,count,sizeof(double),_::cmp); }

                      P 1 Reply Last reply
                      0
                      • M mbue

                        void SortUI(unsigned int* array,const unsigned int count) { typedef struct{ static int cmp(const void *a, const void *b){ return *(int*)a-*(int*)b; } }_; qsort(array,count,sizeof(unsigned int),_::cmp); } void SortSTR(TCHAR** array,const unsigned int count) { typedef struct{ static int cmp(const void *a, const void *b){ return _tcscmp(*(TCHAR**)a,*(TCHAR**)b); } }_; qsort(array,count,sizeof(TCHAR*),_::cmp); } void SortDF(double* array,const unsigned int count) { typedef struct{ static int cmp(const void *a, const void *b){ return *(double*)a<*(double*)b?-1:(*(double*)a>*(double*)b?+1:0); } }_; qsort(array,count,sizeof(double),_::cmp); }

                        P Offline
                        P Offline
                        Paul Michalik
                        wrote on last edited by
                        #12

                        Well, exactly this is the reason, why C# was invented... :)

                        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