When Overloading the Plus Operator, What are Valid Arguments Types?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jehugaleahsa@gmail.com

    When Overloading the Plus Operator, What are Valid Arguments Types?

    Hello:

    Today I learned that the + operator cannot be passed a delegate. I get
    an error from the CLR saying I have an invalid program.

    With that, I was wondering if someone could tell me what other types I
    am not allowed to make parameters.

    Thanks,
    Travis

    class Failer
    {
    public static Failer operator +(Failer failer,
    MulticastDelega te handler)
    {
    return failer;
    }

    public static void Test()
    {
    Failer failer = new Failer();
    object o = failer + new EventHandler(
    delegate(object sender, EventArgs e)
    {
    // DO NOTHING
    });
    }
    }
  • Peter Duniho

    #2
    Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

    On Thu, 11 Sep 2008 13:02:10 -0700, jehugaleahsa@gm ail.com
    <jehugaleahsa@g mail.comwrote:
    Today I learned that the + operator cannot be passed a delegate. I get
    an error from the CLR saying I have an invalid program.
    Please provide a concise-but-complete code sample that reliably
    demonstrates the problem. Also, please state exactly how you run the
    program, exactly what error occurs, and how it's reported.

    I'm not aware of any particular restriction along those lines, and I was
    unable to reproduce the problem. Please see below for a
    concise-but-complete code sample that demonstrates code that works fine on
    my computer.

    Pete

    using System;

    namespace TestDelegateAdd itionOverload
    {
    class Program
    {
    class Test
    {
    public static Test operator +(Test test, MulticastDelega te del)
    {
    return test;
    }
    }

    static void Main(string[] args)
    {
    Test test = new Test();

    test = test + (EventHandler)d elegate(object sender, EventArgs
    e) { };

    Console.WriteLi ne("done");
    Console.ReadLin e();
    }
    }
    }

    Comment

    • jehugaleahsa@gmail.com

      #3
      Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

      Of course It will work if you change my code. Go back to what I sent
      and it will fail.

      Comment

      • Peter Duniho

        #4
        Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

        On Thu, 11 Sep 2008 14:22:44 -0700, jehugaleahsa@gm ail.com
        <jehugaleahsa@g mail.comwrote:
        Of course It will work if you change my code. Go back to what I sent
        and it will fail.
        I demonstrated a concise-but-complete code sample that overloads the +
        operator with a MulticastDelega te argument. That was the only complaint
        in your original post.

        I don't see any material differences between the code you posted and mine,
        except that mine can be compiled and run and yours can't. But even if
        there are material differences that I've overlooked, your question as
        stated has been refuted by my example (you obviously can overload the +
        operator with a MulticastDelega te argument), and you should not expect
        people to bother compiling your code when you haven't provided a complete,
        compilable code sample.

        Pete

        Comment

        • Jeroen Mostert

          #5
          Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

          jehugaleahsa@gm ail.com wrote:
          Today I learned that the + operator cannot be passed a delegate. I get
          an error from the CLR saying I have an invalid program.
          >
          Congratulations , you've discovered a bug! Step right up to Microsoft Connect
          to earn your prize...
          With that, I was wondering if someone could tell me what other types I
          am not allowed to make parameters.
          >
          It's not that, the compiler is emitting invalid IL, and the CLR barfs when
          it encounters it.
          class Failer
          {
          public static Failer operator +(Failer failer,
          MulticastDelega te handler)
          {
          return failer;
          }
          >
          public static void Test()
          {
          Failer failer = new Failer();
          object o = failer + new EventHandler(
          delegate(object sender, EventArgs e)
          {
          // DO NOTHING
          });
          }
          }
          Change this to

          object o = failer + delegate...

          That is, simply omit the explicit instantiation, and it will work. It will
          also work if you use a method rather than an anonymous delegate. Your
          original code is failing because it compiles to something like this:

          ..method public hidebysig static void Test() cil managed
          {
          // Code size 15 (0xf)
          .maxstack 1
          .locals init ([0] class ConsoleApplicat ion2.Failer failer,
          [1] object o)
          IL_0000: nop
          IL_0001: newobj instance void ConsoleApplicat ion2.Failer::.c tor()
          IL_0006: stloc.0
          IL_0007: ldloc.0
          IL_0008: call class ConsoleApplicat ion2.Failer
          ConsoleApplicat ion2.Failer::op _Addition(class ConsoleApplicat ion2.Failer,

          class [mscorlib]System.EventHan dler)
          IL_000d: stloc.1
          IL_000e: ret
          } // end of method Failer::Test

          The call at IL_0008 is invalid because there's only one argument on the
          stack as opposed to the two which are required. There's something going
          wrong here with the magic the compiler uses to create event handlers from
          delegates -- the required code is completely missing!

          The corrected code looks like this:

          ..method public hidebysig static void Test() cil managed
          {
          // Code size 46 (0x2e)
          .maxstack 4
          .locals init ([0] class ConsoleApplicat ion2.Failer failer,
          [1] object o)
          IL_0000: nop
          IL_0001: newobj instance void ConsoleApplicat ion2.Failer::.c tor()
          IL_0006: stloc.0
          IL_0007: ldloc.0
          IL_0008: ldsfld class [mscorlib]System.EventHan dler
          ConsoleApplicat ion2.Failer::'C S$<>9__CachedAn onymousMethodDe legate1'
          IL_000d: brtrue.s IL_0022
          IL_000f: ldnull
          IL_0010: ldftn void ConsoleApplicat ion2.Failer::'< Test>b__0'(obje ct,
          class
          [mscorlib]System.EventArg s)
          IL_0016: newobj instance void
          [mscorlib]System.EventHan dler::.ctor(obj ect,

          native int)
          IL_001b: stsfld class [mscorlib]System.EventHan dler
          ConsoleApplicat ion2.Failer::'C S$<>9__CachedAn onymousMethodDe legate1'
          IL_0020: br.s IL_0022
          IL_0022: ldsfld class [mscorlib]System.EventHan dler
          ConsoleApplicat ion2.Failer::'C S$<>9__CachedAn onymousMethodDe legate1'
          IL_0027: call class ConsoleApplicat ion2.Failer
          ConsoleApplicat ion2.Failer::op _Addition(class ConsoleApplicat ion2.Failer,

          class [mscorlib]System.EventHan dler)
          IL_002c: stloc.1
          IL_002d: ret
          } // end of method Failer::Test

          You see the boilerplate here between IL_0008 and IL_0022 for creating your
          event handler and loading it from a static field.

          --
          J.

          Comment

          • Marc Gravell

            #6
            Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

            Good analysis - one point, though:

            "Change this to object o = failer + delegate..."

            With the code as originally presented (MulticastDeleg ate), you'd need
            to type the delegate:

            o = failer + (EventHandler) delegate {...};

            Of course, a better option would be to declare something more specific
            for the "del" argument - perhaps using the Action<...or Func<...>
            family to clarify the intent (EventHandler is fine too...).

            Marc

            Comment

            • Jeroen Mostert

              #7
              Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

              Marc Gravell wrote:
              Good analysis - one point, though:
              >
              "Change this to object o = failer + delegate..."
              >
              With the code as originally presented (MulticastDeleg ate), you'd need
              to type the delegate:
              >
              o = failer + (EventHandler) delegate {...};
              >
              Oops, you're right, of course. Changing around things a little too
              enthusiasticall y to pin down the root cause.
              Of course, a better option would be to declare something more specific
              for the "del" argument - perhaps using the Action<...or Func<...>
              family to clarify the intent (EventHandler is fine too...).
              >
              Yes, using MulticastDelega te is pretty fishy -- I can't remember a single
              occasion where I had a need to explicitly declare that.

              --
              J.

              Comment

              • jehugaleahsa@gmail.com

                #8
                Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                On Sep 11, 11:01 pm, Jeroen Mostert <jmost...@xs4al l.nlwrote:
                Marc Gravell wrote:
                Good analysis - one point, though:
                >
                "Change this to object o = failer + delegate..."
                >
                With the code as originally presented (MulticastDeleg ate), you'd need
                to type the delegate:
                >
                o = failer + (EventHandler) delegate {...};
                >
                Oops, you're right, of course. Changing around things a little too
                enthusiasticall y to pin down the root cause.
                >
                Of course, a better option would be to declare something more specific
                for the "del" argument - perhaps using the Action<...or Func<...>
                family to clarify the intent (EventHandler is fine too...).
                >
                Yes, using MulticastDelega te is pretty fishy -- I can't remember a single
                occasion where I had a need to explicitly declare that.
                >
                --
                J.
                Thank you. Someone who actually looks at the code I posted, instead of
                just bashing me. It is nice to know that some people try to help
                rather than always question the questions.

                Comment

                • jehugaleahsa@gmail.com

                  #9
                  Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                  On Sep 11, 3:28 pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.com>
                  wrote:
                  On Thu, 11 Sep 2008 14:22:44 -0700, jehugalea...@gm ail.com  
                  >
                  <jehugalea...@g mail.comwrote:
                  Of course It will work if you change my code. Go back to what I sent
                  and it will fail.
                  >
                  I demonstrated a concise-but-complete code sample that overloads the +  
                  operator with a MulticastDelega te argument.  That was the only complaint  
                  in your original post.
                  >
                  I don't see any material differences between the code you posted and mine,  
                  except that mine can be compiled and run and yours can't.  But even if  
                  there are material differences that I've overlooked, your question as  
                  stated has been refuted by my example (you obviously can overload the +  
                  operator with a MulticastDelega te argument), and you should not expect  
                  people to bother compiling your code when you haven't provided a complete,  
                  compilable code sample.
                  >
                  Pete
                  So, in other words, Pete, you don't know why my code doesn't run. The
                  fact of the matter is that I see your code and mine as somewhat
                  functionaly equivilent (aside from mine wrapping the anonymous method
                  inside of a delegate and yours simply using the anonymous method as
                  is).

                  For a typical programmer, the difference doesn't seem significant
                  enough to cause an InvalidProgramE xception. I was hoping someone could
                  explain why the difference would cause the error, regardless what my
                  original, uneducated post asked.

                  Thankfully, my real question was answered without being asked
                  directly. Some times asking the right question is harder than finding
                  the answer.

                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                    On Sep 12, 2:32 pm, "jehugalea...@g mail.com" <jehugalea...@g mail.com>
                    wrote:

                    <snip>
                    Thank you. Someone who actually looks at the code I posted, instead of
                    just bashing me. It is nice to know that some people try to help
                    rather than always question the questions.
                    It's not at all unreasonable to ask for code which is complete,
                    compiles, and demonstrates the problem. Yes, sometimes (as in this
                    case) it's possible for someone to modify the incomplete code when
                    it's presented such that it compiles and shows the described problem -
                    but it's *much* better to ask the question with code which compiles in
                    the first place. Being rude to someone who is trying to help (but
                    hasn't managed to reproduce your error) only serves to discourage
                    people from trying to help you in the future.

                    Jon

                    Comment

                    • Marc Gravell

                      #11
                      Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                      An interesting bug ;-p

                      If you do log it on connect, I'll happily click the "validated" button -
                      'tis definitely a compiler bug.

                      Marc

                      Comment

                      • Peter Duniho

                        #12
                        Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                        On Fri, 12 Sep 2008 06:44:56 -0700, jehugaleahsa@gm ail.com
                        <jehugaleahsa@g mail.comwrote:
                        So, in other words, Pete, you don't know why my code doesn't run.
                        No, I don't. That's my point. If you don't post a complete code sample,
                        _no one_ can know why it doesn't run, unless they put extra effort in to
                        try to add enough code to get your code to run. Once they've done that,
                        they've necessarily got code that's different from yours, and there's no
                        guarantee that even if they can then reproduce a problem, it's the same
                        problem you see.

                        Since you didn't post a complete code sample, I had the option of either
                        trying to wrestle with your code to figure out exactly what you meant, or
                        to simply write my own code based on the text of your question. If all
                        goes well, the time commitment in either scenario is similar, but if not,
                        I could easily wind up spending more time with your code than just writing
                        it myself as I'd write it and still not come up with an answer.

                        It's an obvious choice: write the code oneself, and answer the question
                        that was asked. It's not my fault that your question made a false
                        assumption about the behavior you were seeing, and I don't see why you
                        seem to be taking me to task for answering the question you asked, rather
                        than the question you wish you'd asked.
                        [...]
                        Thankfully, my real question was answered without being asked
                        directly. Some times asking the right question is harder than finding
                        the answer.
                        Yes, you were fortunate that Jeroen was nice enough to do the extra work
                        you should have done yourself by converting your code sample into
                        something that could actually compile. You were also fortunate that
                        having done so, he was able to reproduce the same problem you found. You
                        should indeed be thankful.

                        The fact is, if a person asking a question cannot be bothered to do the
                        basic legwork to prepare a correct, complete question, that person should
                        have no expectation that anyone else will do that work for them. It's
                        great when it happens, but for you to have the attitude that anyone
                        responding to your question _must_ do that is arrogant.

                        You were lucky in this case, but it's worthwhile for you understand what
                        the problem here is with your post and especially your follow-ups. You
                        won't always be so lucky to have someone else willing to do your work for
                        you in the future and it will be good for you to understand the difference
                        between a complete code sample and an incomplete one.

                        Pete

                        Comment

                        • Peter Duniho

                          #13
                          Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                          On Fri, 12 Sep 2008 06:32:58 -0700, jehugaleahsa@gm ail.com
                          <jehugaleahsa@g mail.comwrote:
                          Thank you. Someone who actually looks at the code I posted, instead of
                          just bashing me. It is nice to know that some people try to help
                          rather than always question the questions.
                          No one, least of all me, was "bashing" you. I made simple, reasonable
                          comments.

                          See my other reply for details. Your attitude is in the wrong place.

                          Comment

                          • Jeroen Mostert

                            #14
                            Re: When Overloading the Plus Operator, What are Valid ArgumentsTypes?

                            Peter Duniho wrote:
                            On Fri, 12 Sep 2008 06:44:56 -0700, jehugaleahsa@gm ail.com
                            <jehugaleahsa@g mail.comwrote:
                            >[...]
                            >Thankfully, my real question was answered without being asked
                            >directly. Some times asking the right question is harder than finding
                            >the answer.
                            >
                            Yes, you were fortunate that Jeroen was nice enough to do the extra work
                            you should have done yourself by converting your code sample into
                            something that could actually compile. You were also fortunate that
                            having done so, he was able to reproduce the same problem you found.
                            I'd like to point out that the only reason I did this was because an
                            InvalidProgramE xception always indicates a compiler bug (the compiler should
                            never produce a program that causes this)! If your problem had been less
                            interesting, I might not have bothered. Ditto if I wouldn't have been able
                            to reproduce it.

                            The fact that my analysis helped you should be considered a side effect -- I
                            wasn't actually helping you so much as satisfying my own curiosity.

                            Just to put things in perspective as to who was putting in effort to what end...

                            --
                            J.

                            Comment

                            Working...