Overriding interface members

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

    #1

    Overriding interface members

    Hi,

    I'm confronted with a problem that seems not to be solvable. In
    general: How can I override an interface member of my base class and
    call the overridden method from my derived class?

    This is my class:
    class RemoteXmlDataSo urce : System.Web.UI.W ebControls.XmlD ataSource

    And I want to override
    DataSourceView System.Web.UI.I DataSource.GetV iew(string viewName)
    but I want to make a call to the overridden method right after my
    stuff.

    Declaring the member with override, I get the message
    The modifier 'override' is not valid for this item

    When trying to access the "overridden " member with
    (IDataSource)ba se).GetView(vie wName), I get the message
    Use of keyword 'base' is not valid in this context

    Ok I understand, my interface member completely replaces the member
    from the base class. Is there any way to do this even though?
    I tried something like
    ((IDataSource)( XmlDataSource)t his).GetView(vi ewName)
    but that just calls my new member :)

    That makes deriving much harder than just overriding a virtual method
    and calling base.X()... But I hope I just did not fully understand ;)

    Kind regards, Sebastian

  • Ignacio Machin \( .NET/ C# MVP \)

    #2
    Re: Overriding interface members

    Hi,

    "Sebastian" <sebpaul79.work @googlemail.com wrote in message
    news:1182413815 .648232.224930@ u2g2000hsc.goog legroups.com...
    Hi,
    >
    I'm confronted with a problem that seems not to be solvable. In
    general: How can I override an interface member of my base class and
    call the overridden method from my derived class?
    >
    This is my class:
    class RemoteXmlDataSo urce : System.Web.UI.W ebControls.XmlD ataSource
    >
    And I want to override
    DataSourceView System.Web.UI.I DataSource.GetV iew(string viewName)
    but I want to make a call to the overridden method right after my
    stuff.
    >
    Declaring the member with override, I get the message
    The modifier 'override' is not valid for this item
    Did you declare the base as public virtual?

    See if this code helps you:

    class Program
    {
    static void Main(string[] args)
    {
    B b = new C();
    b.M();

    II i = b;
    i.M();
    Console.Read();
    }
    }

    class B : II
    {
    public virtual void M() { Console.WriteLi ne("B.M"); }
    }
    class C : B
    {
    public override void M()
    {
    Console.WriteLi ne("C.M");
    }
    }

    public interface II
    {
    void M();
    }


    Comment

    • Ben Voigt [C++ MVP]

      #3
      Re: Overriding interface members


      "Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions .comwrote in
      message news:e2BHU4AtHH A.4424@TK2MSFTN GP04.phx.gbl...
      Hi,
      >
      "Sebastian" <sebpaul79.work @googlemail.com wrote in message
      news:1182413815 .648232.224930@ u2g2000hsc.goog legroups.com...
      >Hi,
      >>
      >I'm confronted with a problem that seems not to be solvable. In
      >general: How can I override an interface member of my base class and
      >call the overridden method from my derived class?
      >>
      >This is my class:
      >class RemoteXmlDataSo urce : System.Web.UI.W ebControls.XmlD ataSource
      >>
      >And I want to override
      >DataSourceVi ew System.Web.UI.I DataSource.GetV iew(string viewName)
      >but I want to make a call to the overridden method right after my
      >stuff.
      >>
      >Declaring the member with override, I get the message
      >The modifier 'override' is not valid for this item
      >
      Did you declare the base as public virtual?
      >
      See if this code helps you:
      >
      class Program
      {
      static void Main(string[] args)
      {
      B b = new C();
      b.M();
      >
      II i = b;
      i.M();
      Console.Read();
      }
      }
      >
      class B : II
      {
      public virtual void M() { Console.WriteLi ne("B.M"); }
      I assume that the base class method implements an interface, but doesn't use
      the virtual keyword (that might make it sealed).
      }
      class C : B
      {
      public override void M()
      {
      Console.WriteLi ne("C.M");
      }
      }
      >
      public interface II
      {
      void M();
      }
      >

      Comment

      • Sebastian

        #4
        Re: Overriding interface members

        It turns out that declaring explicit interface implementations as
        virtual is not possible - only implicit interface implementation
        support that. Seems to be a limitation of the C# language. Or is there
        a way I do not see?

        Look at this snippet:

        interface IFace {
        string iFaceMethod();
        }

        public class BaseClass : IFace {
        // works (implicit interface implementation)
        public virtual string iFaceMethod() { return "BaseClass public
        virtual string iFaceMethod()"; }

        // works (explicit interface implementation - obove method won't be
        anymore an implicit interface implementation)
        string IFace.iFaceMeth od() { return "BaseClass string
        IFace.iFaceMeth od()"; }

        // The modifier 'public' is not valid for this item
        // The modifier 'virtual' is not valid for this item
        //public virtual string IFace.iFaceMeth od() { }
        }

        public class DerivedClass : BaseClass, IFace {

        // works
        public override string iFaceMethod() {
        // Use of keyword 'base' is not valid in this context
        //return ((IFace)base).i FaceMethod();

        // works
        //return base.iFaceMetho d(); // calls BaseClass public virtual
        string iFaceMethod()

        return "DerivedCla ss public override string iFaceMethod()";
        }

        // works, but would definitely hide base.iFaceMetho d
        string IFace.iFaceMeth od() {
        // Use of keyword 'base' is not valid in this context
        //return ((IFace)base).i FaceMethod();

        // works
        //return base.iFaceMetho d(); // calls BaseClass public virtual
        string iFaceMethod()

        // works, but leads to infinite recursion
        //return ((IFace)this).i FaceMethod();

        return "DerivedCla ss string IFace.iFaceMeth od()";
        }

        // The modifier 'public' is not valid for this item
        // The modifier 'override' is not valid for this item
        //public override string IFace.iFaceMeth od() { }
        }

        Kind regards, Sebastian

        Comment

        • Ben Voigt [C++ MVP]

          #5
          Re: Overriding interface members


          "Sebastian" <sebpaul79.work @googlemail.com wrote in message
          news:1182939783 .654061.181680@ c77g2000hse.goo glegroups.com.. .
          It turns out that declaring explicit interface implementations as
          virtual is not possible - only implicit interface implementation
          support that. Seems to be a limitation of the C# language. Or is there
          a way I do not see?
          No, you're right. explicit interface implementations are always private
          (therefore can't be virtual), and implicit implementations are always
          public. There's no way to get anything in-between.
          >
          Look at this snippet:
          >
          interface IFace {
          string iFaceMethod();
          }
          >
          public class BaseClass : IFace {
          // works (implicit interface implementation)
          public virtual string iFaceMethod() { return "BaseClass public
          virtual string iFaceMethod()"; }
          >
          // works (explicit interface implementation - obove method won't be
          anymore an implicit interface implementation)
          string IFace.iFaceMeth od() { return "BaseClass string
          IFace.iFaceMeth od()"; }
          >
          // The modifier 'public' is not valid for this item
          // The modifier 'virtual' is not valid for this item
          //public virtual string IFace.iFaceMeth od() { }
          }
          >
          public class DerivedClass : BaseClass, IFace {
          >
          // works
          public override string iFaceMethod() {
          // Use of keyword 'base' is not valid in this context
          //return ((IFace)base).i FaceMethod();
          >
          // works
          //return base.iFaceMetho d(); // calls BaseClass public virtual
          string iFaceMethod()
          >
          return "DerivedCla ss public override string iFaceMethod()";
          }
          >
          // works, but would definitely hide base.iFaceMetho d
          string IFace.iFaceMeth od() {
          // Use of keyword 'base' is not valid in this context
          //return ((IFace)base).i FaceMethod();
          >
          // works
          //return base.iFaceMetho d(); // calls BaseClass public virtual
          string iFaceMethod()
          >
          // works, but leads to infinite recursion
          //return ((IFace)this).i FaceMethod();
          >
          return "DerivedCla ss string IFace.iFaceMeth od()";
          }
          >
          // The modifier 'public' is not valid for this item
          // The modifier 'override' is not valid for this item
          //public override string IFace.iFaceMeth od() { }
          }
          >
          Kind regards, Sebastian
          >

          Comment

          • Sebastian

            #6
            Re: Overriding interface members

            No, you're right. explicit interface implementations are always private
            (therefore can't be virtual), and implicit implementations are always
            public. There's no way to get anything in-between.
            Why are implicit implementations always public and explicit interface
            implementations are always private?
            Is there any logical explanation for that? For me, it sounds just
            stupid. When implementing two methods from different interfaces that
            have the same name, the methods can never be overridden because they
            have to be explicit.

            Kind regards, Sebastian

            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: Overriding interface members

              On Jul 4, 3:19 pm, Sebastian <sebpaul79.w... @googlemail.com wrote:
              No, you're right. explicit interface implementations are always private
              (therefore can't be virtual), and implicit implementations are always
              public. There's no way to get anything in-between.
              >
              Why are implicit implementations always public and explicit interface
              implementations are always private?
              Is there any logical explanation for that? For me, it sounds just
              stupid. When implementing two methods from different interfaces that
              have the same name, the methods can never be overridden because they
              have to be explicit.
              I think I've got a solution, actually. You just need to reimplement
              the interface. You don't specify that you're overriding it, just that
              you're implementing it. Here's some code to demonstrate what I mean -
              if it doesn't do what you want it to, it would be good to know exactly
              what's still missing. Note that you have to redeclare that you're
              implementing IDisposable in the derived class.

              using System;

              public class Base : IDisposable
              {
              void IDisposable.Dis pose()
              {
              Console.WriteLi ne ("Base");
              }
              }

              public class Derived : Base, IDisposable
              {
              void IDisposable.Dis pose()
              {
              Console.WriteLi ne ("Derived");
              }
              }

              public class Test
              {
              static void Main()
              {
              IDisposable a = new Base();
              IDisposable b = new Derived();

              a.Dispose();
              b.Dispose();
              }
              }

              Jon

              Comment

              • Marc Gravell

                #8
                Re: Overriding interface members

                This is a feature of the C# compiler (I believe you have other options
                in VB for instance). You can, however, simply write a protected inner
                method for each, and forward from the explicit interface call - i.e.

                void ISomeInterface. SomeMethod() {SomeInterfaceS omeMethod();}
                void IOtherInterface .SomeMethod() {OtherInterface SomeMethod();}
                protected virtual void SomeInterfaceSo meMethod() {...}
                protected virtual void OtherInterfaceS omeMethod() {...}

                Marc


                Comment

                • Sebastian

                  #9
                  Re: Overriding interface members

                  On Jul 4, 4:33 pm, "Jon Skeet [C# MVP]" <s...@pobox.com wrote:
                  I think I've got a solution, actually. You just need to reimplement
                  the interface. You don't specify that you're overriding it, just that
                  you're implementing it.
                  In that case, you cannot call the overridden method, as it would be
                  possible in virtual methods (base keyword). I tried to show this in my
                  last code example - maybe it's hard legible because of the line
                  wraps...

                  On Jul 4, 4:37 pm, "Marc Gravell" <marc.grav...@g mail.comwrote:
                  This is a feature of the C# compiler
                  LOL In my oppinion it's a defect :D
                  simply write a protected inner
                  method for each, and forward from the explicit interface call
                  Yes this would work. But this is not possible with existing (i.e.
                  built in .NET) classes that do not implement that way...

                  Sebastian

                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: Overriding interface members

                    On Jul 4, 3:56 pm, Sebastian <sebpaul79.w... @googlemail.com wrote:
                    I think I've got a solution, actually. You just need to reimplement
                    the interface. You don't specify that you're overriding it, just that
                    you're implementing it.
                    >
                    In that case, you cannot call the overridden method, as it would be
                    possible in virtual methods (base keyword). I tried to show this in my
                    last code example - maybe it's hard legible because of the line
                    wraps...
                    That's true. It can be done with reflection, but I agree that's pretty
                    grim:

                    void IDisposable.Dis pose()
                    {
                    Console.WriteLi ne ("Derived");
                    InterfaceMappin g mapping =
                    typeof(Base).Ge tInterfaceMap(t ypeof(IDisposab le));
                    MethodInfo method = mapping.TargetM ethods[0];
                    method.Invoke(t his, null);
                    }

                    (I only used 0 blindly because IDisposable has only one member.)

                    Jon

                    Comment

                    • Sebastian

                      #11
                      Re: Overriding interface members

                      That's true. It can be done with reflection, but I agree that's pretty
                      grim
                      Many thanks for your workaround!

                      Nevertheless, I can't imagine that this was the intention by the C#
                      language developers...

                      Kind regards, Sebastian

                      Comment

                      Working...