Proper use of delegates.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Roger Frost

    Proper use of delegates.

    Since we are currently on the subject of multi-threading in a different
    thread, I have a question about delegates.

    When I use delegates, I just create one for each different parameter set
    that I need.

    For example:

    delegate void callBackString( string d_string);

    delegate void callBackStringA rray(string[] d_string);

    delegate void callBackInt(int d_int);

    delegate void callBackSB(stri ng d_string, bool d_bool);



    ....And then I just reuse them when and where I need them.

    Is this the proper way to use delegates?

    I'm highly interested in the most efficient way if this isn't it.

    Thanks

    --
    Roger Frost
    "Logic Is Syntax Independent"

  • Marc Gravell

    #2
    Re: Proper use of delegates.

    Generics - but it is already done for you: consider Action<T>?
    i.e. Action<string>, Action<string[]and Action<intetc match your first 3
    examples

    ..NET 3.5 introduces multi-paramater variants:
    Action<string,b oolmatches your last example

    If the delegate should return a value, then Func<...is also available -
    i.e.
    "int Foo(string arg)" would match Func<string,int >

    Marc


    Comment

    • Roger Frost

      #3
      Re: Proper use of delegates.

      "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
      news:MPG.22288d 315f2fe831956@m snews.microsoft .com...
      Roger Frost <frostrl@hotmai l.comwrote:
      >>
      >When I use delegates, I just create one for each different parameter set
      >that I need.
      >>
      >For example:
      >>
      > delegate void callBackString( string d_string);
      >>
      >>
      >...And then I just reuse them when and where I need them.
      >>
      >Is this the proper way to use delegates?
      >>
      >I'm highly interested in the most efficient way if this isn't it.
      >
      1) You're declaring a type, so use the normal convention for type
      names: Pascal case.
      Conventions are something that I struggle with and hope to get better at.
      When it is just me writing programs, it's not a problem, but I know that I
      need to learn the standards...and I appreciate having my mistakes pointed
      out.
      >
      2) If you're using .NET 3.5 you can use the built-in Action<...>
      delegates; your delegates above are equivalent to
      >
      Action<string>
      Action<string[]>
      Action<int>
      Action<string,b ool>
      >
      Yup .NET 3.5, I will optimize my code for this.

      Thanks!

      Comment

      • Peter Duniho

        #4
        Re: Proper use of delegates.

        On Thu, 21 Feb 2008 23:22:22 -0800, Roger Frost <frostrl@hotmai l.com>
        wrote:
        Since we are currently on the subject of multi-threading in a different
        thread, I have a question about delegates.
        >
        When I use delegates, I just create one for each different parameter set
        that I need.
        >
        [...]
        ...And then I just reuse them when and where I need them.
        >
        Is this the proper way to use delegates?
        Well, for single-parameter delegates that return void, you could just use
        the generic Action<Tdelegat e. So, for example, where you'd declare and
        use "delegate void callBackString( string d_string)", you'd skip the
        declaration and just use "Action<string> " instead where you would have
        used "callBackString " as the type. There's also a no-parameter delegate
        named Action. Non-generic, obviously.

        If you're using .NET 3.5, they've added two, three, and four-parameter
        versions of the same generic type. If you need more than four parameters,
        then you might consider declaring a single generic delegate type for each
        parameter count you need that you reuse as necessary, rather than making a
        new one for each more-than-four-parameter action you have.

        For example:

        delegate void Action<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4
        t4, T5 t5);

        Of course, if you've got more than four parameters for an action, you may
        have other issues. But at least you can avoid making all those delegate
        types. :)

        If you're not using .NET 3.5, then you could of course declare the two-,
        three-, and four-parameter Action delegate types yourself, as with the
        five-parameter example above (except with fewer parameters, of course :) ).

        Pete

        Comment

        • Roger Frost

          #5
          Re: Proper use of delegates.

          Thanks to everyone for the help...here is what I have now:

          private void populateListVie ws(string[] fileList)
          {//Addes the file(s) to the correct ListView Queues.

          //Handle calls from a different thread.
          if (InvokeRequired )
          {//Caller is on a different thread.

          //Create a new delegate.
          Action<string[]cb = new
          Action<string[]>(populateListV iews);

          //Invoke the delegate on the owner thread.
          Invoke(cb, new object[] { fileList });
          }
          else
          {//Caller is on this thread.
          //The good stuff.
          }

          Is this the Proper use of delegates in .NET 3.5?

          If so, can I get a brief run down of what I am gaining over:

          delegate void CallBackStringA rray(string[] d_string);

          [...]

          CallBackString cb = new CallBackString( populateListVie ws);

          Invoke(cb, new object[] { fileList });


          While we are here, how are my conventions in these examples?



          "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
          news:op.t6w1umz 28jd0ej@petes-computer.local. ..
          On Thu, 21 Feb 2008 23:22:22 -0800, Roger Frost <frostrl@hotmai l.com>
          wrote:
          >
          >Since we are currently on the subject of multi-threading in a different
          >thread, I have a question about delegates.
          >>
          >When I use delegates, I just create one for each different parameter set
          >that I need.
          >>
          >[...]
          >...And then I just reuse them when and where I need them.
          >>
          >Is this the proper way to use delegates?
          >
          Well, for single-parameter delegates that return void, you could just use
          the generic Action<Tdelegat e. So, for example, where you'd declare and
          use "delegate void callBackString( string d_string)", you'd skip the
          declaration and just use "Action<string> " instead where you would have
          used "callBackString " as the type. There's also a no-parameter delegate
          named Action. Non-generic, obviously.
          >
          If you're using .NET 3.5, they've added two, three, and four-parameter
          versions of the same generic type. If you need more than four parameters,
          then you might consider declaring a single generic delegate type for each
          parameter count you need that you reuse as necessary, rather than making a
          new one for each more-than-four-parameter action you have.
          >
          For example:
          >
          delegate void Action<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4
          t4, T5 t5);
          >
          Of course, if you've got more than four parameters for an action, you may
          have other issues. But at least you can avoid making all those delegate
          types. :)
          >
          If you're not using .NET 3.5, then you could of course declare the two-,
          three-, and four-parameter Action delegate types yourself, as with the
          five-parameter example above (except with fewer parameters, of course
          :) ).
          >
          Pete

          Comment

          • Roger Frost

            #6
            Re: Proper use of delegates.

            Oops, how about...
            Is this the Proper use of delegates in .NET 3.5?
            >
            If so, can I get a brief run down of what I am gaining over:
            >
            delegate void CallBackStringA rray(string[] d_string);
            >
            [...]
            >
            CallBackStringA rray cb = new CallBackStringA rray(populateLi stViews);
            >
            Invoke(cb, new object[] { fileList });

            Comment

            • Roger Frost

              #7
              Re: Proper use of delegates.

              I really appreciate everyone taking the time to help. I have a problem
              using Jon's example with my string array methods...



              "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
              news:MPG.2228cf 7a15cc1c0395f@m snews.microsoft .com...
              [...] You don't need to declare the variable
              first, and you can just cast to Action<string[]>, giving:
              >
              if (InvokeRequired )
              {
              Invoke ((Action<string >[]) populateListVie ws, fileList);
              }
              else
              {
              ...
              }
              >
              First of all

              Invoke((Action< string>)writeSt atus, newMsg);

              Works fine on my string method, no problem what so ever.

              But...

              Invoke((Action< string>[])populateListVi ews, fileList);

              Doesn't compile, 3 errors:

              1) Cannot convert method group 'populateListVi ews' to non-delegate type
              'System.Action< string>[]'. Did you intend to invoke the method?

              2) The best overloaded method match for
              'System.Windows .Forms.Control. Invoke(System.D elegate, params object[])' has
              some invalid arguments.

              (My method populateListVie ws isn't overloaded, by the way)

              3) Argument '1': cannot convert from 'System.Action< string>[]' to
              'System.Delegat e'



              If I change it to:

              Invoke((Action< string[]>)populateListV iews, fileList);

              (Which is what I think Jon meant in the first place, as far as I can tell
              due to the compile time errors above.)

              It compiles fine, but at run time I get a "Parameter count mismatch." logic
              error.

              My method is: private void populateListVie ws(string[] fileList){...}

              And the call is: populateListVie ws(Directory.Ge tFiles(folderPa th));

              Directory.GetFi les() returns string[], and my logic was fine when I was
              declaring my own delegate or Action<string[]cb = new
              Action<string[]>(populateListV iews);


              I have tried several different combinations, some compiled and some didn't,
              but the ones that compiled always raise that same logic error. What am I
              missing?



              --
              Roger Frost
              "Logic Is Syntax Independent"

              Comment

              • jehugaleahsa@gmail.com

                #8
                Re: Proper use of delegates.

                To be honest, I preferred you earlier example. I believe a delegate
                should be named after what it is doing, not given a generic name based
                on its parameters and return type. It is convenient to use built-in
                delegates, but do they tell readers anything? Look at
                Converter<TInpu t, TOutput>, it is one of the most useful delegate
                definitions out there - it take something, it returns something. But,
                if I'm not converting anything, why am I adding my method name into
                it?

                I say, using 3.0's delegates is fine because, well, you are forced to
                (and they usually make sense). However, especially when doing UI
                threading delegates, make as many delegates as you need so that
                delegate names make sense. It is no different than finding good names
                for any other variable.

                I'm not sure why not to use better names and why anyone would suggest
                replacing a good name with a more generic one.

                IMHO,
                Travis

                Comment

                • Marc Gravell

                  #9
                  Re: Proper use of delegates.

                  make as many delegates as you need so that
                  delegate names make sense
                  Additional to Jon's reply...

                  If I see a delegate argument JoesCustomWossi t, then if I'm not
                  familiar I need to look up what the interface is from the metadata/
                  docs. However, if I see a delegate argument Func<float,floa t,bool>
                  then I know that it takes 2 floats and returns a bool. Combine that
                  with the argument name that hopefully indicates its purpose, and I
                  have everything I need to start coding.

                  Marc

                  Comment

                  • Chris Shepherd

                    #10
                    Re: Proper use of delegates.

                    Peter Duniho wrote:
                    [...]
                    You need better co-workers. Seriously.
                    I had to laugh when I read this -- I've felt the OP's pain on more than one
                    occasion at both my current place of employ and previous ones.
                    This is probably the appropriate (well, *accurate*) response to probably two
                    thirds of the lengthy discussions that take place here that mention work
                    environment in any way.

                    Chris.

                    Comment

                    • Peter Duniho

                      #11
                      Re: Proper use of delegates.

                      On Mon, 25 Feb 2008 05:27:03 -0800, Chris Shepherd <chsh@nospam.ch sh.ca>
                      wrote:
                      If my understanding is correct, there's no funny business. The second
                      parameter is a *params* object[]
                      Ah, right. It's funny...I was actually looking for that "params" keyword
                      in the docs, and didn't see it. When I went back and looked at the exact
                      same page I'd looked at before, sure enough there it was.

                      I think someone is messing with my head. :)

                      Pete

                      Comment

                      Working...