Constructors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Morris [Droopy eyes software]

    Constructors

    I have an object persistence framework I have written, this framework
    expects every object to descend ultimately from PersistentObjec t and to have
    a constructor (ObjectSpace objectSpace) so that objects may be recreated.

    PersistentObjec t's constructor will do something like this

    this.ObjectSpac e = objectSpace;
    objectSpace.Reg isterObjectCrea tion(this);

    The object space will record a reference to this new object + do something
    like this

    if (!IsLoadingFrom Database)
    newInstance.Aft erConstruction( );


    The virtual AfterConstructi on method on a class is therefore only ever
    called when an object is initially created and not when it is recreated due
    to being fetched from the database. This gives a good opportunity to create
    composite objects etc. Here is my problem

    public class CustomerAction : PersistentObjec t
    {
    public CustomerAction( Customer customer)
    : base(customer.O bjectSpace)
    {
    this.Customer = customer;
    }

    protected override void AfterConstructi on()
    {
    //Do some stuff with this.Customer
    }
    }

    My problem is that this.Customer has not been set by the time
    AfterConstructi on is called.

    1) new CustomerAction( someCustomer);
    2) CustomerAction constructor is called
    3) Base constructor (customer.Objec tSpace is called)
    4) CustomerAction. AfterConstructi on is called
    5) CustomerAction constructor code is executed

    Why oh why wont dotnet let me execute some of my own code before calling the
    base constructor? I can do this in methods.

    I find it so restrictive!



  • Peter Bromberg [C# MVP]

    #2
    RE: Constructors

    Peter,
    I don't mean to sound disrespectful, but I've observed that often when
    people make complaints like yours it is because they have engineering flaws
    in their code pattern, not because the Framework is "restrictiv e". Perhaps
    you ought to consider refactoring your design pattern?
    Peter

    --
    Co-founder, Eggheadcafe.com developer portal:

    UnBlog:





    "Peter Morris [Droopy eyes software]" wrote:
    I have an object persistence framework I have written, this framework
    expects every object to descend ultimately from PersistentObjec t and to have
    a constructor (ObjectSpace objectSpace) so that objects may be recreated.
    >
    PersistentObjec t's constructor will do something like this
    >
    this.ObjectSpac e = objectSpace;
    objectSpace.Reg isterObjectCrea tion(this);
    >
    The object space will record a reference to this new object + do something
    like this
    >
    if (!IsLoadingFrom Database)
    newInstance.Aft erConstruction( );
    >
    >
    The virtual AfterConstructi on method on a class is therefore only ever
    called when an object is initially created and not when it is recreated due
    to being fetched from the database. This gives a good opportunity to create
    composite objects etc. Here is my problem
    >
    public class CustomerAction : PersistentObjec t
    {
    public CustomerAction( Customer customer)
    : base(customer.O bjectSpace)
    {
    this.Customer = customer;
    }
    >
    protected override void AfterConstructi on()
    {
    //Do some stuff with this.Customer
    }
    }
    >
    My problem is that this.Customer has not been set by the time
    AfterConstructi on is called.
    >
    1) new CustomerAction( someCustomer);
    2) CustomerAction constructor is called
    3) Base constructor (customer.Objec tSpace is called)
    4) CustomerAction. AfterConstructi on is called
    5) CustomerAction constructor code is executed
    >
    Why oh why wont dotnet let me execute some of my own code before calling the
    base constructor? I can do this in methods.
    >
    I find it so restrictive!
    >
    >
    >
    >

    Comment

    • Joanna Carter [TeamB]

      #3
      Re: Constructors

      "Peter Morris [Droopy eyes software]" <pete@droopyeye s.no.com.spama écrit
      dans le message de news: %23sO51Y$qGHA.4 100@TK2MSFTNGP0 2.phx.gbl...

      | The virtual AfterConstructi on method on a class is therefore only ever
      | called when an object is initially created and not when it is recreated
      due
      | to being fetched from the database. This gives a good opportunity to
      create
      | composite objects etc. Here is my problem
      |
      | public class CustomerAction : PersistentObjec t
      | {
      | public CustomerAction( Customer customer)
      | : base(customer.O bjectSpace)
      | {
      | this.Customer = customer;
      | }
      |
      | protected override void AfterConstructi on()
      | {
      | //Do some stuff with this.Customer
      | }
      | }

      Then, if you are setting the Customer property from the constructor, why not
      simply use the Customer property setter to do anything after the property is
      set ?

      | Why oh why wont dotnet let me execute some of my own code before calling
      the
      | base constructor? I can do this in methods.
      |
      | I find it so restrictive!

      There is always a way around this, it just requires a change of perspective
      :-)

      Joanna

      --
      Joanna Carter [TeamB]
      Consultant Software Engineer


      Comment

      • Laura T

        #4
        Re: Constructors

        "Why oh why wont dotnet let me execute some of my own code before calling
        the base constructor? "

        Oh, it's not dotnet problem. It's not a problem at all.
        If you are a child (your object) of someone (your parent object), your
        parent must be alive before you can be alive.
        That's why it's mandatory that the parent object is constructed first before
        your object.
        Rethink your design.



        "Peter Morris [Droopy eyes software]" <pete@droopyeye s.no.com.spamha
        scritto nel messaggio news:%23sO51Y$q GHA.4100@TK2MSF TNGP02.phx.gbl. ..
        >I have an object persistence framework I have written, this framework
        >expects every object to descend ultimately from PersistentObjec t and to
        >have a constructor (ObjectSpace objectSpace) so that objects may be
        >recreated.
        >
        PersistentObjec t's constructor will do something like this
        >
        this.ObjectSpac e = objectSpace;
        objectSpace.Reg isterObjectCrea tion(this);
        >
        The object space will record a reference to this new object + do something
        like this
        >
        if (!IsLoadingFrom Database)
        newInstance.Aft erConstruction( );
        >
        >
        The virtual AfterConstructi on method on a class is therefore only ever
        called when an object is initially created and not when it is recreated
        due to being fetched from the database. This gives a good opportunity to
        create composite objects etc. Here is my problem
        >
        public class CustomerAction : PersistentObjec t
        {
        public CustomerAction( Customer customer)
        : base(customer.O bjectSpace)
        {
        this.Customer = customer;
        }
        >
        protected override void AfterConstructi on()
        {
        //Do some stuff with this.Customer
        }
        }
        >
        My problem is that this.Customer has not been set by the time
        AfterConstructi on is called.
        >
        1) new CustomerAction( someCustomer);
        2) CustomerAction constructor is called
        3) Base constructor (customer.Objec tSpace is called)
        4) CustomerAction. AfterConstructi on is called
        5) CustomerAction constructor code is executed
        >
        Why oh why wont dotnet let me execute some of my own code before calling
        the base constructor? I can do this in methods.
        >
        I find it so restrictive!
        >
        >
        >

        Comment

        • Thomas T. Veldhouse

          #5
          Re: Constructors

          Laura T <laura.t@_yahoo .comwrote:
          "Why oh why wont dotnet let me execute some of my own code before calling
          the base constructor? "
          >
          That works in C++ correctly [in my opinion], but it doesn't work in .NET. It
          is very annoying to work around. I wish it were possible to put:

          // constructor
          public SubClass(int variable) {
          // do something here
          base(variable);
          }
          Oh, it's not dotnet problem. It's not a problem at all.
          If you are a child (your object) of someone (your parent object), your
          parent must be alive before you can be alive.
          That's why it's mandatory that the parent object is constructed first before
          your object.
          Rethink your design.
          >
          I think it is inconvenient at best. You can easily do such things in C++
          without issue.

          --
          Thomas T. Veldhouse
          Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

          Comment

          • Joanna Carter [TeamB]

            #6
            Re: Constructors

            "Peter Bromberg [C# MVP]" <pbromberg@yaho o.nospammin.com a écrit dans le
            message de news: 702D0BA7-AFE6-4F45-A9C5-18BEB335839D@mi crosoft.com...

            | I don't mean to sound disrespectful, but I've observed that often when
            | people make complaints like yours it is because they have engineering
            flaws
            | in their code pattern, not because the Framework is "restrictiv e".
            Perhaps
            | you ought to consider refactoring your design pattern?

            I'm sorry Peter, but I know Pete Morris' work and it is not flaws in his
            engineering pracices.

            Peter, like I, comes from a Delphi background; a language which allows code
            before the call to the inherited constructor.

            When you have used a language like Delphi or C++ that allows this practice,
            then you tend to design towards the capabilities of those languages. Moving
            to a different language that has different features does take some getting
            used to and I guess that P.M. will have to refactor, just as I have.

            However, moving existing design patterns to a different language is not a
            trivial task, but it is definitely *not* because of design failures.

            Joanna

            --
            Joanna Carter [TeamB]
            Consultant Software Engineer


            Comment

            • Joanna Carter [TeamB]

              #7
              Re: Constructors

              "Laura T" <laura.t@_yahoo .coma écrit dans le message de news:
              Okb$R9ArGHA.164 8@TK2MSFTNGP02. phx.gbl...

              | Oh, it's not dotnet problem. It's not a problem at all.
              | If you are a child (your object) of someone (your parent object), your
              | parent must be alive before you can be alive.
              | That's why it's mandatory that the parent object is constructed first
              before
              | your object.
              | Rethink your design.

              This is almost arrogant and doesn't consider the fact that Peter is a
              skilled programmer and is making the transition from Delphi, C#'s parent;
              which does allow code before inherited constructor calls.

              That's why you have to consider that if it weren't for Delphi, you wouldn't
              be using C# :-)

              Joanna

              --
              Joanna Carter [TeamB]
              Consultant Software Engineer


              Comment

              • Thomas T. Veldhouse

                #8
                Re: Constructors

                Joanna Carter [TeamB] <joanna@not.for .spamwrote:
                >
                This is almost arrogant and doesn't consider the fact that Peter is a
                skilled programmer and is making the transition from Delphi, C#'s parent;
                which does allow code before inherited constructor calls.
                >
                If anything, C++ is C#'s parent. In reality, I think Java is <duck!!!>.
                That's why you have to consider that if it weren't for Delphi, you wouldn't
                be using C# :-)
                >
                Yahoo ... Pascal was late in the OO game ... and Borland did it with Turbo
                Pascal (I used to love programming in TurboVision when the whole world was DOS
                and DPMI).

                --
                Thomas T. Veldhouse
                Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

                Comment

                • Joanna Carter [TeamB]

                  #9
                  Re: Constructors

                  "Thomas T. Veldhouse" <veldy71@yahoo. coma écrit dans le message de news:
                  FI6dnYucMt58WiL ZnZ2dnUVZ_uidnZ 2d@giganews.com...

                  | If anything, C++ is C#'s parent. In reality, I think Java is <duck!!!>.

                  <g>

                  My allusion is to the fact that Anders Heijlsberg (sp?) was architect on
                  Delphi before doing the same for C# :-)

                  Joanna

                  --
                  Joanna Carter [TeamB]
                  Consultant Software Engineer


                  Comment

                  • Thomas T. Veldhouse

                    #10
                    Re: Constructors

                    Joanna Carter [TeamB] <joanna@not.for .spamwrote:
                    "Thomas T. Veldhouse" <veldy71@yahoo. coma ?crit dans le message de news:
                    FI6dnYucMt58WiL ZnZ2dnUVZ_uidnZ 2d@giganews.com...
                    >
                    | If anything, C++ is C#'s parent. In reality, I think Java is <duck!!!>.
                    >
                    <g>
                    >
                    My allusion is to the fact that Anders Heijlsberg (sp?) was architect on
                    Delphi before doing the same for C# :-)
                    >
                    Gotcha ... I didn't know that. Good old Microsoft ate up its little cousin
                    ;-)

                    --
                    Thomas T. Veldhouse
                    Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

                    Comment

                    • Peter Morris [Droopy eyes software]

                      #11
                      Re: Constructors

                      Oh, it's not dotnet problem. It's not a problem at all.
                      If you are a child (your object) of someone (your parent object), your
                      parent must be alive before you can be alive.
                      I don't think that is quite right. I believe that the object instance
                      exists immediately, all constructors actually do is to initialise the
                      members of the instance. So why can't I explicitly specify the order in
                      which initialisation occurs as I can with virtual methods?



                      Comment

                      • Peter Morris [Droopy eyes software]

                        #12
                        Re: Constructors

                        Then, if you are setting the Customer property from the constructor, why
                        not
                        simply use the Customer property setter to do anything after the property
                        is
                        set ?
                        Because the value should effectively be readonly. In such a case I'd like
                        to ensure that the code will not compile unless I pass a customer.

                        But there are other considerations too, for example

                        public Class1
                        {
                        public Class1(Customer customer)
                        {
                        this.Customer = Customer;
                        do some stuff with customer, create some child objects etc
                        }
                        }


                        public SpecialClass1 : Class1
                        {
                        public SpecialClass1(C ustomer customer) : base(customer)
                        {
                        //this class is special so needs some special checks first
                        if (!DoSpecialChec ks(customer))
                        throw new SomeExceptionTy pe("The special checks failed");
                        }
                        }

                        Why should I go through potentially lots of base constructors + create all
                        the child objects etc (which may be expensive to create in terms of
                        resources) only to eventually be denied the possibility of creating the
                        object instance? It would be much better as this

                        public SpecialClass1 : Class1
                        {
                        public SpecialClass1(C ustomer customer)
                        {
                        //this class is special so needs some special checks first
                        if (!DoSpecialChec ks(customer))
                        throw new SomeExceptionTy pe("The special checks failed");

                        base(customer);
                        }
                        }


                        Or what if the parent constructor expects an ObjectSpace?

                        public ChildClass : PersistentObjec t
                        {
                        public ChildClass(Cust omer customer)
                        {
                        if (customer == null)
                        throw new ArgumentNullExc eption("ChildCl ass constructor - customer");
                        if (customer.Objec tSpace == null)
                        throw new ArgumentExcepti on("ChildClass constructor - customer has no
                        object space");

                        base(customer.O bjectSpace);
                        }
                        }

                        So instead of my nicely formatted + (more importantly) expected exception
                        types I get a NullReferenceEx ception because I can't write the code exactly
                        how I just did, the base constructor is called before my code gets a chance
                        to execute.

                        There are lots of reasons why someone might want to initialise code before
                        the base constructor code executes, I find it quite restrictive that I
                        cannot do it.

                        Pete


                        Comment

                        • Joanna Carter [TeamB]

                          #13
                          Re: Constructors

                          "Peter Morris [Droopy eyes software]" <pete@droopyeye s.no.com.spama écrit
                          dans le message de news: uI7JtDDrGHA.329 2@TK2MSFTNGP03. phx.gbl...

                          | I don't think that is quite right. I believe that the object instance
                          | exists immediately, all constructors actually do is to initialise the
                          | members of the instance.

                          Not in .NET; even Delphi for .NET doesn't allow anything before the
                          inherited constructor.

                          ..NET constructors really do create the object and until you have reached the
                          constructor in the root class of a hierarchy, the object does not yet exist.
                          That seems to be the model that .NET follows.

                          | So why can't I explicitly specify the order in
                          | which initialisation occurs as I can with virtual methods?

                          Because C# doesn't support virtual static methods and constructors are a
                          special case static method ?

                          Joanna

                          --
                          Joanna Carter [TeamB]
                          Consultant Software Engineer


                          Comment

                          • Joanna Carter [TeamB]

                            #14
                            Re: Constructors

                            "Thomas T. Veldhouse" <veldy71@yahoo. coma écrit dans le message de news:
                            NJCdnaAgC7OdTyL ZnZ2dnUVZ_vqdnZ 2d@giganews.com...

                            | Gotcha ... I didn't know that. Good old Microsoft ate up its little
                            cousin
                            | ;-)

                            Whoa!! Delphi is still very much alive and well. What is more it is one of
                            the few languages that can provide a single code base that will compile to
                            both Win32 *and* .NET.

                            Joanna

                            --
                            Joanna Carter [TeamB]
                            Consultant Software Engineer


                            Comment

                            • Joanna Carter [TeamB]

                              #15
                              Re: Constructors

                              "Peter Morris [Droopy eyes software]" <pete@droopyeye s.no.com.spama écrit
                              dans le message de news: Ojt3yJDrGHA.382 0@TK2MSFTNGP05. phx.gbl...

                              | Because the value should effectively be readonly. In such a case I'd like
                              | to ensure that the code will not compile unless I pass a customer.

                              Then you can have a split-visibility property where the setter is less
                              visible than the getter

                              public Customer Customer
                              {
                              get { return customer; }
                              private set
                              {
                              // other stuff
                              customer = value;
                              }

                              | But there are other considerations too, for example
                              |
                              | public Class1
                              | {
                              | public Class1(Customer customer)
                              | {
                              | this.Customer = Customer;
                              | do some stuff with customer, create some child objects etc
                              | }
                              | }

                              | Or what if the parent constructor expects an ObjectSpace?
                              |
                              | public ChildClass : PersistentObjec t
                              | {
                              | public ChildClass(Cust omer customer)
                              | {
                              | if (customer == null)
                              | throw new ArgumentNullExc eption("ChildCl ass constructor - customer");
                              | if (customer.Objec tSpace == null)
                              | throw new ArgumentExcepti on("ChildClass constructor - customer has no
                              | object space");
                              |
                              | base(customer.O bjectSpace);
                              | }
                              | }

                              Aaah! in this case, you can use a private static method to do the checks,
                              etc on the incoming parameter, something like this :

                              class CustomerAction
                              {
                              private Customer customer;

                              private static Customer DoSomething(Cus tomer customer)
                              {
                              return customer;
                              }

                              private CustomerAction( Customer customer, object dummy) : base()
                              {
                              this.customer = customer;
                              }

                              public CustomerAction( Customer customer) : this(DoSomethin g(customer),
                              null) { }
                              }

                              Joanna

                              --
                              Joanna Carter [TeamB]
                              Consultant Software Engineer


                              Comment

                              Working...