Newbie Delegate Question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • damiensawyer@yahoo.com.au

    #1

    Newbie Delegate Question

    Hi,

    Can someone please explain to me something about delegates?

    My understanding is as follows. A delegate is basically an object that
    can hold a reference to a "method" somewhere. That is, it's
    essentially a pointer to a piece of code somewhere else in memory.

    It therefore (to me anyway) makes sense to define delegates with their
    signatures and be able to use those signatures at different points in
    code. That way, if the signatures of various methods are defined by
    the delegate, you 'know' that you can store references to those
    methods in your delegates.

    My question is, is there a way to define a method, referring to a
    delegate to source it's parameter list?

    I hope this makes sense. Please feel free to pull me up if I'm missing
    the point completely.

    Thanks in advance.


    Damien



    --------- working sample --------

    <%@ Page Language="C#" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://
    www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt d">

    <script runat="server">

    public delegate void WriteLogHandler (WriteLogEventH andler
    args); // note - deliberately left out "object Sender" parameter to
    keep demo simple.
    public class WriteLogEventHa ndler : EventArgs
    {
    private string message;
    public WriteLogEventHa ndler(string Message)
    {
    message = Message;
    }
    public string Message
    {
    get{return message;}
    }
    }

    public class Person
    {
    public event WriteLogHandler WriteLog;

    public void FireAnEvent()
    {
    if (WriteLog != null) WriteLog(new
    WriteLogEventHa ndler("Hello Delegate World"));
    }
    }

    protected void Page_Load(objec t sender, EventArgs e)
    {
    Person SamplePerson = new Person();
    SamplePerson.Wr iteLog += new
    WriteLogHandler (SamplePerson_W riteLog);
    SamplePerson.Fi reAnEvent();
    }

    /// The question I have is, can I pass in some reference to
    "WriteLogHandle r"
    /// as the argument to the below method? By doing it the way it is
    below, I have to keep the delegate and
    /// this signiture (and however many others) in sync.
    void SamplePerson_Wr iteLog(WriteLog EventHandler args)
    {
    this.Form.Inner Html += args.Message + "<br/>";
    }

    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title>Untitl ed Page</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <h3>Delegate Primer</h3>
    </div>
    </form>
    </body>
    </html>
  • .\\\\axxx

    #2
    Re: Newbie Delegate Question

    If I understand what you are asking, then no, you cant do it.
    Are you saying you want to change the signature in one place (the
    delegate definition) and to have that change update all methods that
    are used with that delegate to have the same signature?

    I can (sort of ) see where you are coming from - but if the signature
    changes, one would think that (usually) you would need to change the
    content of any methods whose signature has changed, anyway (.e.g if
    your WriteLogEventHa ndler needed an extra parameter to specify the
    colour of the output (I know it's not a good example, but it's late)
    then you would have to change not only the signature of the method,
    but also the content - and one method's parameter name may sensibly be
    "debugColou r" while another may be "errorColou r" (again, crap examples
    but I hope you see where I am coming from!).

    I think if delegates more of being references to particualr methods -
    not just to method signatures. Sure, you can have a generic delegate
    that would 'point' to any method with a particular signature - but
    then you have the issue when only a subset of the methods you
    reference change their signature.

    So if you think of the delegate as being a reference to some
    functionalilty, rather than a particular signature, you may end up
    with more delegates, but I think you may find it a more robust
    solution in the long run.

    Alternately you could define a delegate which defines collection of
    objects as its parameter, and define all your 'delegatable methods' in
    the same manner - then the signature would never change- you just add
    another object to the collection... ;)




    On Jun 11, 1:13 pm, "damiensaw...@y ahoo.com.au"
    <damiensaw...@y ahoo.com.auwrot e:
    Hi,
    >
    Can someone please explain to me something about delegates?
    >
    My understanding is as follows. A delegate is basically an object that
    can hold a reference to a "method" somewhere. That is, it's
    essentially a pointer to a piece of code somewhere else in memory.
    >
    It therefore (to me anyway) makes sense to define delegates with their
    signatures and be able to use those signatures at different points in
    code. That way, if the signatures of various methods are defined by
    the delegate, you 'know' that you can store references to those
    methods in your delegates.
    >
    My question is, is there a way to define a method, referring to a
    delegate to source it's parameter list?
    >
    I hope this makes sense. Please feel free to pull me up if I'm missing
    the point completely.
    >
    Thanks in advance.
    >
    Damien
    >
    --------- working sample --------
    >
    <%@ Page Language="C#" %>
    >
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dt d">
    >
    <script runat="server">
    >
    public delegate void WriteLogHandler (WriteLogEventH andler
    args); // note - deliberately left out "object Sender" parameter to
    keep demo simple.
    public class WriteLogEventHa ndler : EventArgs
    {
    private string message;
    public WriteLogEventHa ndler(string Message)
    {
    message = Message;
    }
    public string Message
    {
    get{return message;}
    }
    }
    >
    public class Person
    {
    public event WriteLogHandler WriteLog;
    >
    public void FireAnEvent()
    {
    if (WriteLog != null) WriteLog(new
    WriteLogEventHa ndler("Hello Delegate World"));
    }
    }
    >
    protected void Page_Load(objec t sender, EventArgs e)
    {
    Person SamplePerson = new Person();
    SamplePerson.Wr iteLog += new
    WriteLogHandler (SamplePerson_W riteLog);
    SamplePerson.Fi reAnEvent();
    }
    >
    /// The question I have is, can I pass in some reference to
    "WriteLogHandle r"
    /// as the argument to the below method? By doing it the way it is
    below, I have to keep the delegate and
    /// this signiture (and however many others) in sync.
    void SamplePerson_Wr iteLog(WriteLog EventHandler args)
    {
    this.Form.Inner Html += args.Message + "<br/>";
    }
    >
    </script>
    >
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title>Untitl ed Page</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <h3>Delegate Primer</h3>
    </div>
    </form>
    </body>
    </html>

    Comment

    • damiensawyer@yahoo.com.au

      #3
      Re: Newbie Delegate Question

      If I understand what you are asking, then no, you cant do it.

      Bummer.
      Are you saying you want to change the signature in one place (the
      delegate definition)  and to have that change update all methods that
      are used with that delegate to have the same signature?
      Exactly!
      I can (sort of ) see where you are coming from - but if the signature
      changes, one would think that (usually) you would need to change the
      content of any methods whose signature has changed, anyway
      hmmm... good point.
      I think if (of?) delegates more of being references to particualr methods -
      not just to method signatures.
      Sure. However this comes back to my original point. If you had said "I
      think of a delegate more of being references to a particular
      method" (as in, one single method) then I'd understand completely.

      However, if a (single) delegate is to hold references to "multiple
      methods" (hence the point of having a delegate 'variable' in the first
      place) - then it would seem to me to syntactically make sense to be
      able to define/modify all of those methods in a combined way. See my
      point? Either delegates are 'meant' to refer to single methods or
      multiple. It would seem, by the ommission of the syntax construct I
      was asking about, that the designers may have been thinking single (or
      maybe have just considered such a construct 'syntactic sugar').


      Sure, you can have a generic delegate
      that would 'point' to any method with a particular signature - but
      then you have the issue when only a subset of the methods you
      reference change their signature.
      Good point. However is that issue any different under the current
      design?

      So if you think of the delegate as being a reference to some
      functionalilty, rather than a particular signature, you may end up
      with more delegates, but I think you may find it a more robust
      solution in the long run.
      I'm not 100% sure what you're getting at here... I'll have to mull
      this one over.
      Alternately you could define a delegate which defines collection of
      objects as its parameter, and define all your 'delegatable methods' in
      the same manner - then the signature would never change- you just add
      another object to the collection... ;)
      *grin*.


      Thanks for your help :-)

      Comment

      • .\\\\axxx

        #4
        Re: Newbie Delegate Question

        What I was getting at (sorry - I'm using google groups and I'm not
        sure how to answer in-line) is that you seem to be thinking of
        delegates and their associated methods in terms of their signatures,
        rather than what functions they perform.

        public void ShowMessageOnFo rm(string message){...}
        and
        public void DeleteFile(stri ng path){...} have the same signature, and
        therefore could have the same delegate - but I would always use a
        different delegate for each.

        Sure that's an extreme example - but I tend to think that being
        specific with a delegate reduces problems down the line when one of
        the methods may require a signature change while the other does not.

        So I have 'Form change Event' delegates (note plural) which are used
        to refer to all events on all forms in my appliciation, each of which
        implement an interface specifying the event handler signature, but
        each of them is defined independently because the information required
        _may_ change independently of all others (e.g. a change in the
        customer maintenance form may require additional information to be
        processed by the event handler, such as an email address to send an
        email to, while a change to other forms may simply need to inform that
        a change of some description has been made).

        Now with many forms, this is a large number of identically signatured
        delegates - but the maintenance is simple if a single signature
        changes - and if multiple signatures change thn I did some poor design
        in the first place and deserve the angst of changing them all :)

        In thinking about this, I can't see a greason why what you are asking
        for would not be possible as a pre-compilation event.

        So you'd define your signature

        #preprocess myDelegateSig "(sting param1, string param2)

        and your delegate

        public delegate <myDelegateSigM yEventHandler;

        and your method(s)

        public <myDelegateSigm yMethod
        {
        MessageBox.Show (param1 + param2);
        }

        if you fogive my made-up syntax - but you probably get the idea...

        So, in principle it could be possible - but I'm not sure that it
        really helps.

        Cheers




        On Jun 11, 2:23 pm, "damiensaw...@y ahoo.com.au"
        <damiensaw...@y ahoo.com.auwrot e:
        If I understand what you are asking, then no, you cant do it.
        >
        Bummer.
        >
        Are you saying you want to change the signature in one place (the
        delegate definition) and to have that change update all methods that
        are used with that delegate to have the same signature?
        >
        Exactly!
        >
        I can (sort of ) see where you are coming from - but if the signature
        changes, one would think that (usually) you would need to change the
        content of any methods whose signature has changed, anyway
        >
        hmmm... good point.
        >
        I think if (of?) delegates more of being references to particualr methods -
        not just to method signatures.
        >
        Sure. However this comes back to my original point. If you had said "I
        think of a delegate more of being references to a particular
        method" (as in, one single method) then I'd understand completely.
        >
        However, if a (single) delegate is to hold references to "multiple
        methods" (hence the point of having a delegate 'variable' in the first
        place) - then it would seem to me to syntactically make sense to be
        able to define/modify all of those methods in a combined way. See my
        point? Either delegates are 'meant' to refer to single methods or
        multiple. It would seem, by the ommission of the syntax construct I
        was asking about, that the designers may have been thinking single (or
        maybe have just considered such a construct 'syntactic sugar').
        >
        Sure, you can have a generic delegate
        that would 'point' to any method with a particular signature - but
        then you have the issue when only a subset of the methods you
        reference change their signature.
        >
        Good point. However is that issue any different under the current
        design?
        >
        So if you think of the delegate as being a reference to some
        functionalilty, rather than a particular signature, you may end up
        with more delegates, but I think you may find it a more robust
        solution in the long run.
        >
        I'm not 100% sure what you're getting at here... I'll have to mull
        this one over.
        >
        Alternately you could define a delegate which defines collection of
        objects as its parameter, and define all your 'delegatable methods' in
        the same manner - then the signature would never change- you just add
        another object to the collection... ;)
        >
        *grin*.
        >
        Thanks for your help :-)

        Comment

        • Peter Duniho

          #5
          Re: Newbie Delegate Question

          On Tue, 10 Jun 2008 21:23:58 -0700, damiensawyer@ya hoo.com.au
          <damiensawyer@y ahoo.com.auwrot e:
          >If I understand what you are asking, then no, you cant do it.
          >
          Bummer.
          >
          >Are you saying you want to change the signature in one place (the
          >delegate definition)  and to have that change update all methods that
          >are used with that delegate to have the same signature?
          >
          Exactly!
          In that case, it seems to me that you might as well just define a single
          type that is _the_ argument to any method that would use that
          "signature" . Then if you change the type itself, the signature of the
          method is effectively changed.

          Of course, you still have the issue that if you're changing the type, that
          presumably means the methods taking that type would or should be changed
          to take advantage of or otherwise deal with the change. But whatever. :)
          [...]
          >I think if (of?) delegates more of being references to particualr
          >methods -
          >not just to method signatures.
          >
          Sure. However this comes back to my original point. If you had said "I
          think of a delegate more of being references to a particular
          method" (as in, one single method) then I'd understand completely.
          >
          However, if a (single) delegate is to hold references to "multiple
          methods" (hence the point of having a delegate 'variable' in the first
          place) - then it would seem to me to syntactically make sense to be
          able to define/modify all of those methods in a combined way. See my
          point?
          I see your point, but only in the sense that it relies on a basic
          misunderstandin g of what a delegate is.

          The delegate is _not_ the method signature itself. Because it's strongly
          typed, it can of course reference only methods that match the signature
          given. But the value stored in a delegate is no more the signature than
          the value stored in something declared "int" is itself a description of an
          "int". Just as the value stored in an "int" isn't a description of an
          "int" (it's an actual int!), the value stored in a delegate type isn't a
          signature (i.e. description) of a method, but rather is a referece to the
          actual method itself.

          As far as the more specific question of "methods" versus "method" goes:
          there is the Delegate and MulticastDelega te type. Due to a quirk in the
          design evolution of .NET, these are basically the same thing. In other
          words, any delegate variable can hold a reference to more than one method
          in its invocation list. There's no such thing as a delegate that can only
          reference one method.

          Even if there were, it would refer to the specific _method_, not some
          description of a method.

          On top of all that, keep in mind that when you set a delegate to a value,
          you're not necessarily just referencing the method. For instance methods,
          you are referencing the method _and_ the instance that will be used to
          invoke the method. Again, this is far from a _description_ (signature) of
          the method. It's a reference to the actual method and how you're going to
          call it.

          In other words, the delegate type isn't a way to describe a method. It's
          a type that holds references _to_ methods, and to do so specifically in a
          way that can immediately lead to calling those methods.
          Either delegates are 'meant' to refer to single methods or
          multiple. It would seem, by the ommission of the syntax construct I
          was asking about, that the designers may have been thinking single (or
          maybe have just considered such a construct 'syntactic sugar').
          Not at all. They are "meant" to do both, and they aren't just "syntactic
          sugar". They are a fundamental type in C#, practically as fundamental as
          other built-in types. They are sort of like function pointers in C/C++,
          but with some additional flexibility in their behavior.

          The designers definitely weren't thinking of delegates in the way that you
          are, but it wasn't just something they overlooked. There's a fundamental
          difference between what a delegate type actually is, as compared to how
          you seem to want to use it.

          Pete

          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: Newbie Delegate Question

            On Jun 11, 4:13 am, "damiensaw...@y ahoo.com.au"
            <damiensaw...@y ahoo.com.auwrot e:
            Can someone please explain to me something about delegates?
            You might want to read
            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

            My understanding is as follows. A delegate is basically an object that
            can hold a reference to a "method" somewhere. That is, it's
            essentially a pointer to a piece of code somewhere else in memory.
            Sort of. Actually all delegates are (potentially) multicast in .NET -
            so it's a reference to a list of methods. Each method also has a
            target associated with it - essentially which object to call the
            method on. (This is null for static methods.)
            It therefore (to me anyway) makes sense to define delegates with their
            signatures and be able to use those signatures at different points in
            code. That way, if the signatures of various methods are defined by
            the delegate, you 'know' that you can store references to those
            methods in your delegates.
            I personally tend to use the new Func and Action delegate types
            in .NET 3.5 - they mean I don't need to sprinkle my code with delegate
            type declarations.
            My question is, is there a way to define a method, referring to a
            delegate to source it's parameter list?
            No, I'm afraid not.
            --------- working sample --------
            Console applications are generally a lot better for samples than
            ASP.NET applications. With a full console app, I can just copy, paste
            and compile straight from the command line. No need to create an
            ASP.NET project, bring up a web server etc. However:
            /// The question I have is, can I pass in some reference to
            "WriteLogHandle r"
            /// as the argument to the below method? By doing it the way it is
            below, I have to keep the delegate and
            /// this signiture (and however many others) in sync.
            void SamplePerson_Wr iteLog(WriteLog EventHandler args)
            Have you actually had problems with this in practice? How often do you
            change delegate signatures? When you change a delegate signature,
            you'll probably need to change all the implementing methods anyway, or
            at least check that they're still valid with all the new parameters.

            Jon

            Comment

            • damiensawyer@yahoo.com.au

              #7
              Re: Newbie Delegate Question

              Thanks heaps for that guys, I think it's clearing up.

              [Quoting .\axxx]
              In that case, it seems to me that you might as well just define a single
              type that is _the_ argument to any method that would use that
              "signature" . Then if you change the type itself, the signature of the
              method is effectively changed.
              In my original post, I guess that's effectively what
              WriteLogEventHa ndler is?

              [Quoting Peter]
              I see your point, but only in the sense that it relies on a basic
              misunderstandin g of what a delegate is.
              Yep - I think that you're right.
              On top of all that, keep in mind that when you set a delegate to a value,
              you're not necessarily just referencing the method. For instance methods,
              you are referencing the method _and_ the instance that will be used to
              invoke the method.
              Ok.... that's definitely along different lines than what I've been
              thinking... but starting to make sense. By adding 'instances' to each
              method, it sort of adds another whole dimension to the puzzle. I think
              now that I can start to imagine better what delegates should be
              doing...
              But the value stored in a delegate is no more the signature than
              the value stored in something declared "int" is itself a description of an
              "int"
              Great descrption!

              [Quoting Jon]
              I personally tend to use the new Func and Action delegate types
              in .NET 3.5 - they mean I don't need to sprinkle my code with delegate
              type declarations.
              Not heard of these before. I'll look them up.
              >My question is, is there a way to define a method, referring to a
              >delegate to source it's parameter list?
              >No, I'm afraid not.
              I think that I have a better understanding of their purpose now which
              is great.


              Thanks guys for all your help :-)




              DS

              Comment

              Working...