• Visitors can check out the Forum FAQ by clicking this link. You have to register before you can post: click the REGISTER link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. View our Forum Privacy Policy.
  • Want to receive the latest contracting news and advice straight to your inbox? Sign up to the ContractorUK newsletter here. Every sign up will also be entered into a draw to WIN £100 Amazon vouchers!

.NET overloads/shadows

Collapse
X
  •  
  • Filter
  • Time
  • Show
Clear All
new posts

    .NET overloads/shadows

    Ok, so a base class has a method in it. It's not virtual. A derived class needs a slightly different implementation. Can't override because it's not virtual. VB tells one to declare it overloads. Run everything up, in the debugger it's fine. The overload is called.

    But, the binding is actually done at compile time. This gives rise to:-

    - Deploy the assembly with the derived class. No changes to behaviour. The method in the base class is still called.

    - Recompile the client code. Deploy it. No changes other than compilation. The method in the derived class is now called.

    I accept this happens, and why it happens (call not callvirt). But surely there are no circumstances in which it can be though of as correct. Why does the compiler allow a method to be overloads/shadows when it is not going to call it until the client is recompiled.

    [/rant]

    #2
    Hrm,

    That doesn't sound right. I've had a derived class with an overloaded method call correctly without having to recompile the client code. Are you sure the reference is pulling from the correct place, and its not running from a version in the GAC?

    Comment


      #3
      Originally posted by Weltchy View Post
      Hrm,

      That doesn't sound right. I've had a derived class with an overloaded method call correctly without having to recompile the client code. Are you sure the reference is pulling from the correct place, and its not running from a version in the GAC?
      Absolutely sure (but that doesn't make me right!).

      Obviously it's not possible to reproduce it in the IDE without twiddling build setting etc. Heres how to do it (for the terminally bored).

      - Create a baseclass with a "SomeMethod" returning "from base".
      - Create a derived class
      - Create a client, instance derived class and write result or some method to console

      Copy exe and dll somewhere convenient.
      Run it.

      - Now update the derived class to overload the method returning "from derived"
      - Copy new derived class
      - Run and watch in amazement as it fails to call the overload. [Or laugh at my expense of course]

      Recompile the client and now it will call the overload.

      Now, maybe this is because it is VB (but I don't think so, it happens with Cobol as well). But it most definitely occurs on my machine which VS2005 SP1.

      Comment


        #4
        I may have the wrong end of the stick here, but it is how the compiler determines which overload to call when there is some ambiguity.

        http://blogs.extremeoptimization.com...2/10/7134.aspx

        http://msdn2.microsoft.com/en-us/library/tb18a48w.aspx

        Comment


          #5
          Originally posted by DimPrawn View Post
          I may have the wrong end of the stick here, but it is how the compiler determines which overload to call when there is some ambiguity.

          http://blogs.extremeoptimization.com...2/10/7134.aspx

          http://msdn2.microsoft.com/en-us/library/tb18a48w.aspx
          There is no ambiguity, it's when the binding actually happens which is the problem.

          public class A
          Function fx as String
          return "from base"
          end function
          end class

          public class B Inherits A
          end class

          And the client code

          sub Main

          dim ob as new b
          console.write ob.fx

          end sub

          This is all fine.

          Now I change B as

          public class B Inherits A
          overloads function fx as string
          return "From Derived"
          end class

          Build and deploy B.

          Behaviour is unchanged. Oops.

          Rebuild the client and it now calls the overload.

          So, what I think is happening is that at compile time the function is resolved as an IL.CALL. Thus it will call whatever was resolved at compile time. Because it is not marked as overridable it is not producing a CALLVIRT.

          When the client is recompiled it resolves to the overload in the derived class. Again with an IL CALL.

          It seems to me that Overloads - of a base class method - should not be allowed when the base class method is not virtual. Because this is going to break existing clients. [Unfortunately in VB at least the compiler demand you overload it].

          To be fair, you'll never see the the problem in testing. Only in partial deployment.

          Comment


            #6
            Don't know about VB, or .NET for that matter, but how else is going to work? If it's not virtual it means it's a straight function call, and when the function doesn't exist in B it's a straight call to the one in A. It can't know in advance that you're going to do something different later.

            You're expecting the compiler to insert some extra code to look for a derived version at runtime, which is exactly what happens with virtual functions.

            So the answer is a) use virtual, or b) deploy the things that need to be deployed.

            It's perfectly okay for this to be allowed; it would never be a problem in a single EXE or DLL. It's only because you're trying to combine one half of the program with another half from a previous build, and haven't designed it to allow that.
            Will work inside IR35. Or for food.

            Comment


              #7
              Hrm,

              In C#, i'd change the overloads to new. I'll give this a go when I get some time and see what happens. I've got a funny feeling I've run across this before, just have to remember what i changed

              Comment


                #8
                C#

                You are talking about overloads (same method name, different parameters) or overrides (same method signature, but replacing the definition in a base class).

                Everyone seems to be mixing overloads and overrides and I ain't got a clue what's going on.

                It didn't help that I downed 10 pints last night and got about 4 hours sleep either.

                Comment


                  #9
                  Originally posted by VectraMan View Post
                  Don't know about VB, or .NET for that matter, but how else is going to work? If it's not virtual it means it's a straight function call, and when the function doesn't exist in B it's a straight call to the one in A. It can't know in advance that you're going to do something different later.

                  You're expecting the compiler to insert some extra code to look for a derived version at runtime, which is exactly what happens with virtual functions.

                  So the answer is a) use virtual, or b) deploy the things that need to be deployed.

                  It's perfectly okay for this to be allowed; it would never be a problem in a single EXE or DLL. It's only because you're trying to combine one half of the program with another half from a previous build, and haven't designed it to allow that.
                  Well, I wouldn't argue with much of that. Except for "and when the function doesn't exist in B". Since the client is calling B.Something I don't think it is entirely unreasonable to expect B.Something to be called.

                  Comment


                    #10
                    Originally posted by DimPrawn View Post
                    You are talking about overloads (same method name, different parameters) or overrides (same method signature, but replacing the definition in a base class).

                    Everyone seems to be mixing overloads and overrides and I ain't got a clue what's going on.

                    It didn't help that I downed 10 pints last night and got about 4 hours sleep either.
                    To paraphrase VectraMan I'm cheating and been bitten.

                    It's an overload with the same parameters (equivalent to "new" I think in C#). [I guess the fundamental problem is being allowed to overload a method in a base class with a method in a derived class with an identical signature]

                    Comment

                    Working...
                    X