Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Inheritance Problem. Can I do this?

Inheritance Problem. Can I do this?

Scheduled Pinned Locked Moved C#
helporacledesignagentic-aioop
7 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TheFoZ
    wrote on last edited by
    #1

    Hi All. I have a StaffMember class in my app that is inherited by my data access layer to StaffMemberOracleUDT. My reasoning for this is that the OracleUDT version has the data access part needed to convert an Oracle object to something I can use and then I can just send back the StaffMember base to be used in the UI layer. The problem I'm having is that I need to access the properties in the base class (Name, ID etc) but I also need to over ride these in the inherited class as each property needs a special OracleObjectMappingAttribute added to it that cannot be added to the base as I would then need to reference the Data Access Layer in my UI layer which shouldn't really be done. Any help is greatly appreciated.

    The FoZ

    D 1 Reply Last reply
    0
    • T TheFoZ

      Hi All. I have a StaffMember class in my app that is inherited by my data access layer to StaffMemberOracleUDT. My reasoning for this is that the OracleUDT version has the data access part needed to convert an Oracle object to something I can use and then I can just send back the StaffMember base to be used in the UI layer. The problem I'm having is that I need to access the properties in the base class (Name, ID etc) but I also need to over ride these in the inherited class as each property needs a special OracleObjectMappingAttribute added to it that cannot be added to the base as I would then need to reference the Data Access Layer in my UI layer which shouldn't really be done. Any help is greatly appreciated.

      The FoZ

      D Offline
      D Offline
      dojohansen
      wrote on last edited by
      #2

      The short answer is "yes". :) I think it's a slightly odd dependency pattern you're creating - your DALs will depend on the business layer - but it is possible. And you don't need to reference the DAL from the UI - just the business layer. In your business layer you'll have:

      public class StaffMember
      {
      virtual public string Name { get; set; }
      }

      and in the Oracle DAL

      public class StaffMemberOracle : StaffMember
      {
      [SomeAttribute]
      override public string Name { get; set; }
      }

      You never actually "convert" between these two types: The derived class IS the base class plus something of it's own.

      public StaffMember LoadStaffMember(int id)
      {
      // Returns instances of derives classes like StaffMemberOracle.
      // Even though the declared return type is "StaffMember", if you
      // return an instance of StaffMemberOracle, the attribute on the
      // Name property is present.
      switch (DB)
      {
      case "Oracle": return OracleDAL.LoadStaffMember(id);
      case "MSSQL": return MssqlDAL.LoadStaffMember(id);
      ...
      }
      }

      Not that I'd do that! Rather than have a bunch of switches in every method in the business layer that uses the DAL, create an interface that all DALs implement. Then your code will be something like

      public StaffMember LoadStaffMember(int id)
      {
      return CreateDAL().LoadStaffMember(id);
      }

      public Something LoadSomething(int id)
      {
      return CreateDAL().LoadSomething(id);
      }

      IDAL CreateDAL()
      {
      get
      {
      switch (DB)
      {
      case "O": return new OracleDAL();
      case "MS": return new MsSqlDAL();
      ...
      }
      }
      }

      HTH

      T 1 Reply Last reply
      0
      • D dojohansen

        The short answer is "yes". :) I think it's a slightly odd dependency pattern you're creating - your DALs will depend on the business layer - but it is possible. And you don't need to reference the DAL from the UI - just the business layer. In your business layer you'll have:

        public class StaffMember
        {
        virtual public string Name { get; set; }
        }

        and in the Oracle DAL

        public class StaffMemberOracle : StaffMember
        {
        [SomeAttribute]
        override public string Name { get; set; }
        }

        You never actually "convert" between these two types: The derived class IS the base class plus something of it's own.

        public StaffMember LoadStaffMember(int id)
        {
        // Returns instances of derives classes like StaffMemberOracle.
        // Even though the declared return type is "StaffMember", if you
        // return an instance of StaffMemberOracle, the attribute on the
        // Name property is present.
        switch (DB)
        {
        case "Oracle": return OracleDAL.LoadStaffMember(id);
        case "MSSQL": return MssqlDAL.LoadStaffMember(id);
        ...
        }
        }

        Not that I'd do that! Rather than have a bunch of switches in every method in the business layer that uses the DAL, create an interface that all DALs implement. Then your code will be something like

        public StaffMember LoadStaffMember(int id)
        {
        return CreateDAL().LoadStaffMember(id);
        }

        public Something LoadSomething(int id)
        {
        return CreateDAL().LoadSomething(id);
        }

        IDAL CreateDAL()
        {
        get
        {
        switch (DB)
        {
        case "O": return new OracleDAL();
        case "MS": return new MsSqlDAL();
        ...
        }
        }
        }

        HTH

        T Offline
        T Offline
        TheFoZ
        wrote on last edited by
        #3

        Thanks for you reply but I am having a few problems. I have set it out like you have above but my properties have private members associated to them. If I have code in the get & set on the base I get an error in the inherited class "inherited.staffid.set cannot override inherited member base.StaffID.set because it is not marked virtual, abstract or overrride." My base class property is marked virtual and the inherited is marked override.

        public class StaffMember
        {
        protected int staffID;

        virtual public int StaffID
        {
            get { return staffID; }
            set { staffID = value }
        }
        

        }

        public class StaffMemberOracle : StaffMember, INullable, IOracleCustomType
        {
        [OracleObjectMappingAttribute("STAFFID")]
        override void int StaffID
        {
        get { return staffID; }
        set { staffID = value }
        }
        }

        I think I may be going about this the wrong way. Cheers

        The FoZ

        D T 2 Replies Last reply
        0
        • T TheFoZ

          Thanks for you reply but I am having a few problems. I have set it out like you have above but my properties have private members associated to them. If I have code in the get & set on the base I get an error in the inherited class "inherited.staffid.set cannot override inherited member base.StaffID.set because it is not marked virtual, abstract or overrride." My base class property is marked virtual and the inherited is marked override.

          public class StaffMember
          {
          protected int staffID;

          virtual public int StaffID
          {
              get { return staffID; }
              set { staffID = value }
          }
          

          }

          public class StaffMemberOracle : StaffMember, INullable, IOracleCustomType
          {
          [OracleObjectMappingAttribute("STAFFID")]
          override void int StaffID
          {
          get { return staffID; }
          set { staffID = value }
          }
          }

          I think I may be going about this the wrong way. Cheers

          The FoZ

          D Offline
          D Offline
          dojohansen
          wrote on last edited by
          #4

          override void int StaffID should be override public int StaffID.

          1 Reply Last reply
          0
          • T TheFoZ

            Thanks for you reply but I am having a few problems. I have set it out like you have above but my properties have private members associated to them. If I have code in the get & set on the base I get an error in the inherited class "inherited.staffid.set cannot override inherited member base.StaffID.set because it is not marked virtual, abstract or overrride." My base class property is marked virtual and the inherited is marked override.

            public class StaffMember
            {
            protected int staffID;

            virtual public int StaffID
            {
                get { return staffID; }
                set { staffID = value }
            }
            

            }

            public class StaffMemberOracle : StaffMember, INullable, IOracleCustomType
            {
            [OracleObjectMappingAttribute("STAFFID")]
            override void int StaffID
            {
            get { return staffID; }
            set { staffID = value }
            }
            }

            I think I may be going about this the wrong way. Cheers

            The FoZ

            T Offline
            T Offline
            TheFoZ
            wrote on last edited by
            #5

            Sorry that was a typo! I think I have solved it. I need to use the new keyword new public int StaffID to declare a new version of the property. Intellisense seems to like it :) Thanks for your effort

            The FoZ

            D 1 Reply Last reply
            0
            • T TheFoZ

              Sorry that was a typo! I think I have solved it. I need to use the new keyword new public int StaffID to declare a new version of the property. Intellisense seems to like it :) Thanks for your effort

              The FoZ

              D Offline
              D Offline
              dojohansen
              wrote on last edited by
              #6

              No, you don't need "new". You need "override". The "new" keyword is for member *hiding*, not overriding. To understand why, you need to know about the difference between virtual and non-virtual members, also often described as "late-bound" and "early-bound" members. It's also helpful to understand the concepts of reference types and value types. A couple resources I dug up for you quickly (you may want to google for others if they don't work for you): Value Types vs Reference Types[^] Virtual Members vs Non-Virtual[^] Or google "polymorphism" and these other terms I've mentioned. In brief, virtual members work as follows: When a member is accessed, such as method Foo(), the implementation of that method is resolved ("bound") at run-time, based on the run-time (actual) type of the object. For non-virtual members, the implementation is resolved at compile time (when you compile), based on the declared type of the reference. For example: public class A { virtual public string Foo() { return "A.Foo()"; } } public class B : A { override public string Foo() { return "B.Foo()"; } } void test() { A obj = new A(); MessageBox.Show(obj.Foo()); // "A.Foo()" obj = new B(); // Now, "obj" is still of declared type "A", but run-time type "B". MessageBox.Show(obj.Foo()); // "B.Foo()" } If instead you declared A.Foo without the virtual keyword and used new to hide this method in B, the second call to "obj.Foo" would still resolve to A.Foo, because obj is of declared type A.

              T 1 Reply Last reply
              0
              • D dojohansen

                No, you don't need "new". You need "override". The "new" keyword is for member *hiding*, not overriding. To understand why, you need to know about the difference between virtual and non-virtual members, also often described as "late-bound" and "early-bound" members. It's also helpful to understand the concepts of reference types and value types. A couple resources I dug up for you quickly (you may want to google for others if they don't work for you): Value Types vs Reference Types[^] Virtual Members vs Non-Virtual[^] Or google "polymorphism" and these other terms I've mentioned. In brief, virtual members work as follows: When a member is accessed, such as method Foo(), the implementation of that method is resolved ("bound") at run-time, based on the run-time (actual) type of the object. For non-virtual members, the implementation is resolved at compile time (when you compile), based on the declared type of the reference. For example: public class A { virtual public string Foo() { return "A.Foo()"; } } public class B : A { override public string Foo() { return "B.Foo()"; } } void test() { A obj = new A(); MessageBox.Show(obj.Foo()); // "A.Foo()" obj = new B(); // Now, "obj" is still of declared type "A", but run-time type "B". MessageBox.Show(obj.Foo()); // "B.Foo()" } If instead you declared A.Foo without the virtual keyword and used new to hide this method in B, the second call to "obj.Foo" would still resolve to A.Foo, because obj is of declared type A.

                T Offline
                T Offline
                TheFoZ
                wrote on last edited by
                #7

                Thanks for your reply but it wouldn't work for me earlier. Probably to much going on. Just tried and it is working. Thanks again for you help.

                The FoZ

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups