Inheritance of constructors.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • A n g l e r

    Inheritance of constructors.

    Hi all.

    I'm facing the following construction:

    class ClOld
    {
    public ClOld(string a) { ... }
    }

    class ClNew: ClOld
    {
    SomeData[] arr;
    public ClNew(string a, SomeObject b): base(a)
    {
    arr = new SomeData[] {b.data1, b.data2, b.data3 };
    }
    }

    Now, I wonder how to pass initialized arr to a base constructor. Why
    can't I code something like below:

    class ClOld
    {
    public ClOld(string a, ref SomeData[] arr) { ... }
    }

    class ClNew: ClOld
    {
    SomeData[] arr;
    public ClNew(string a, SomeObject b):
    {
    arr = new SomeData[] {b.data1, b.data2, b.data3 };
    base(a, ref arr);
    }
    }


    Thanks in advance,
    Pete
  • Jon Skeet [C# MVP]

    #2
    Re: Inheritance of constructors.

    On Jun 30, 12:17 pm, A n g l e r <p|k|o|n|i|u|.. .@h-o-t-m-a-i-l.c_o_m>
    wrote:
    I'm facing the following construction:
    <snip>
    Now, I wonder how to pass initialized arr to a base constructor. Why
    can't I code something like below:
    <snip>

    Basically you can't write any actual code in the constructor before
    the base constructor call. You *can* make a static method call, so you
    can do:

    public ClNew(string a) : base(a, CreateArray())
    {
    // Other stuff
    }

    That won't help you for a ref parameter, however. Are you sure you
    need a ref parameter in the constructor call? That's pretty unusual.

    Jon

    Comment

    • A n g l e r

      #3
      Re: Inheritance of constructors.

      Basically you can't write any actual code in the constructor before
      the base constructor call. You *can* make a static method call, so you
      can do:
      Brilliant, I thought so. Blooming drawbacks of the garbage collector and
      the whole automated memory management by ms, right? :/
      public ClNew(string a) : base(a, CreateArray())
      {
      // Other stuff
      }
      That will help for now :)
      That won't help you for a ref parameter, however. Are you sure you
      need a ref parameter in the constructor call? That's pretty unusual.
      No, I guess I don't cos I pass just an array of objects which anyway
      means (I guess so) it's handled in a similar way to reference. Isn't it?

      DataGridView[] arr = new DataGridView[] { grid1, grid2, grid3 };

      Cheers,
      P.

      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: Inheritance of constructors.

        On Jun 30, 1:43 pm, A n g l e r <p|k|o|n|i|u|.. .@h-o-t-m-a-i-l.c_o_m>
        wrote:
        Basically you can't write any actual code in the constructor before
        the base constructor call. You *can* make a static method call, so you
        can do:
        >
        Brilliant, I thought so. Blooming drawbacks of the garbage collector and
        the whole automated memory management by ms, right? :/
        Well, it's more that doing things within an object before it's been
        initialized in the parent is somewhat questionable.

        <snip>
        That won't help you for a ref parameter, however. Are you sure you
        need a ref parameter in the constructor call? That's pretty unusual.
        >
        No, I guess I don't cos I pass just an array of objects which anyway
        means (I guess so) it's handled in a similar way to reference. Isn't it?
        >
        DataGridView[] arr = new DataGridView[] { grid1, grid2, grid3 };
        There's a big difference between "pass by reference" and "pass
        reference by value". It confuses quite a lot of people, and it's well
        worth being aware of the difference. It's mostly down to confusingly
        named terminology, IMO.

        See http://pobox.com/~skeet/csharp/parameters.html

        Jon

        Comment

        • A n g l e r

          #5
          Re: Inheritance of constructors.

          Well, it's more that doing things within an object before it's been
          initialized in the parent is somewhat questionable.
          Consider an example where a new class (for instance it's constructor) is
          in charge of the data preparation which is fed to a parent class
          constructor. OK, you can pass it via static variable as suggested,
          though what happens if you want to have different data in it for each
          instance of a new class? Unless static in C# means it exists over the
          whole cycle of a code execution but doesn't limit it to one global data
          copy shared amongst all instances like in C++. Is this the case?
          There's a big difference between "pass by reference" and "pass
          reference by value". It confuses quite a lot of people, and it's well
          worth being aware of the difference. It's mostly down to confusingly
          named terminology, IMO.
          >
          See http://pobox.com/~skeet/csharp/parameters.html
          Sure, it's just all happens on different levels. The actual reference is
          all about where it is in the memory. The value reference is more like a
          container that is being copied while passing.

          Thanks,
          P.

          Comment

          • A n g l e r

            #6
            Re: Inheritance of constructors.

            Consider an example where a new class (for instance it's constructor) is
            in charge of the data preparation which is fed to a parent class
            constructor. OK, you can pass it via static variable as suggested,
            though what happens if you want to have different data in it for each
            instance of a new class? Unless static in C# means it exists over the
            whole cycle of a code execution but doesn't limit it to one global data
            copy shared amongst all instances like in C++. Is this the case?
            Erm, OK, I see what happens in this case. It's passed via static method,
            the value reference is stored locally in a base class. No harm done
            unless I would prefer it would be capable of following every change of
            the value reference in outer classes ... what then?

            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: Inheritance of constructors.

              On Jun 30, 2:35 pm, A n g l e r <p|k|o|n|i|u|.. .@h-o-t-m-a-i-l.c_o_m>
              wrote:
              Well, it's more that doing things within an object before it's been
              initialized in the parent is somewhat questionable.
              >
              Consider an example where a new class (for instance it's constructor) is
              in charge of the data preparation which is fed to a parent class
              constructor. OK, you can pass it via static variable as suggested,
              though what happens if you want to have different data in it for each
              instance of a new class? Unless static in C# means it exists over the
              whole cycle of a code execution but doesn't limit it to one global data
              copy shared amongst all instances like in C++. Is this the case?
              I didn't suggest a static *variable*. I suggested a static *method*.
              The method should be able to construct the information required for
              the base class's constructor which no information about the current
              (uninitialized) instance.
              There's a big difference between "pass by reference" and "pass
              reference by value". It confuses quite a lot of people, and it's well
              worth being aware of the difference. It's mostly down to confusingly
              named terminology, IMO.
              >
              Seehttp://pobox.com/~skeet/csharp/parameters.html
              >
              Sure, it's just all happens on different levels. The actual reference is
              all about where it is in the memory. The value reference is more like a
              container that is being copied while passing.
              Not sure what you mean by "value reference" but the point is that
              there's a big difference between
              void Foo(ref object[] x)
              and
              void Foo(object[] x)
              even though object[] is a reference type. I rarely see a genuine need
              for the former signature.

              Jon

              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: Inheritance of constructors.

                On Jun 30, 2:48 pm, A n g l e r <p|k|o|n|i|u|.. .@h-o-t-m-a-i-l.c_o_m>
                wrote:
                Consider an example where a new class (for instance it's constructor) is
                in charge of the data preparation which is fed to a parent class
                constructor. OK, you can pass it via static variable as suggested,
                though what happens if you want to have different data in it for each
                instance of a new class? Unless static in C# means it exists over the
                whole cycle of a code execution but doesn't limit it to one global data
                copy shared amongst all instances like in C++. Is this the case?
                >
                Erm, OK, I see what happens in this case. It's passed via static method,
                the value reference is stored locally in a base class. No harm done
                unless I would prefer it would be capable of following every change of
                the value reference in outer classes ... what then?
                I don't really understand what you mean by the last sentence. Could
                you give a concrete example in code of what you'd like to be able to
                do?

                Jon

                Comment

                • A n g l e r

                  #9
                  Re: Inheritance of constructors.

                  I don't really understand what you mean by the last sentence. Could
                  you give a concrete example in code of what you'd like to be able to
                  do?
                  Ok, here it goes:

                  class ClOld
                  {
                  public SomeData[] arr;
                  public ClOld(string a, SomeData[] b) { arr=b; }
                  }

                  class ClNew: ClOld
                  {
                  static SomeData[] arr;
                  static SomeData[] StaticPassing(S omeClass src)
                  {
                  arr = new SomeData[] { src.d1, src.d2, src.d3 };
                  return arr;
                  }

                  public void UpdateArr(src)
                  {
                  arr = new SomeData[] { src.d1, src.d2, src.d3 };
                  // the arr is now assigned a new reference by value
                  // though, this doesn't mean that base.arr is also updated
                  // with a new reference value unless
                  // I'll update it on myself, for instance base.arr=arr; or more
                  //likely by set, get that act on arr while it remains the
                  // private member of ClOld

                  //also, if I made the arr public in thr ClNew and modified its
                  //reference by value from outside of the ClNew class, I'd have
                  //to handle some further updating actions which is inconvenient
                  }

                  public ClNew(string a, SomeObject b): base(a, StaticCopier())
                  {
                  }
                  }

                  ClNew aa= new ClNew(src);
                  aa.arr=new SomeData[] { data }

                  // aa.base.arr stays unchanged unless I'll update it. In case of memory
                  // references it wouldn't be any concern as long as all this happens in
                  // one thread

                  Comment

                  • A n g l e r

                    #10
                    Re: Inheritance of constructors.

                    Not sure what you mean by "value reference" but the point is that
                    Sorry, I mean reference by value which indicates that the reference is
                    copied and isn't maintained automatically by another instances of the
                    actual "reference by value" container :d

                    class1 aa=new class1("d1");
                    bb=aa;
                    aa= new class1("d2");

                    bb still contains d1
                    aa contains d2

                    while in case of memory-wise C++ reference
                    bb would contain d2
                    aa would contain also d2

                    Therefore I said that reference by value is like a container of
                    reference. It helps you avoid copying of the whole objects, but you have
                    to maintain on your own the actual copies of the references ...

                    Comment

                    • Jon Skeet [C# MVP]

                      #11
                      Re: Inheritance of constructors.

                      On Jun 30, 3:23 pm, A n g l e r <p|k|o|n|i|u|.. .@h-o-t-m-a-i-l.c_o_m>
                      wrote:
                      I don't really understand what you mean by the last sentence. Could
                      you give a concrete example in code of what you'd like to be able to
                      do?
                      <snip>
                      // aa.base.arr stays unchanged unless I'll update it. In case of memory
                      // references it wouldn't be any concern as long as all this happens in
                      // one thread
                      Your example is made somewhat trickier by the fact that one variable
                      is static, the other isn't, but they both have the same name. Avoiding
                      making fields public helps too :) I'm also not sure where threading
                      comes into it particularly...

                      But yes, your point that the field is a just reference rather than
                      something which automatically keeps track of a different variable is
                      correct. I can't remember when I've ever wanted the latter behaviour
                      though.

                      Jon

                      Comment

                      • A n g l e r

                        #12
                        Re: Inheritance of constructors.

                        Avoiding
                        making fields public helps too :)
                        Bare in mind that was just for sake of example.
                        >I'm also not sure where threading
                        comes into it particularly...
                        It just comes in the sense that you wouldn't like your data collection
                        being modified while reading. In case of "reference by value" that's not
                        a problem cos it never gets updated anyway - just remains stuck with an
                        old collection unless you do something on your own, lol.
                        But yes, your point that the field is a just reference rather than
                        something which automatically keeps track of a different variable is
                        correct. I can't remember when I've ever wanted the latter behaviour
                        though.
                        Imagine a class which handles rendering at 15 frames a second. Now,
                        imagine that you have a collection of objects it renders to screen or
                        wherever you fancy. Do you really desire to inform the class that some
                        objects are added/removed from the data collection? I'd rather have a
                        memory-wise reference that assures the class would always see the
                        updated collection. What's the point in copying reference values of
                        let's say 1000 objects 15 times a second (provided collection changes so
                        dynamically)?

                        Cheers

                        Comment

                        • Jon Skeet [C# MVP]

                          #13
                          Re: Inheritance of constructors.

                          On Jun 30, 5:09 pm, A n g l e r <p|k|o|n|i|u|.. .@h-o-t-m-a-i-l.c_o_m>
                          wrote:
                           Avoiding
                          >
                          making fields public helps too :)
                          >
                          Bare in mind that was just for sake of example.
                          Unfortunately the duplication of variable names made it hard for me to
                          see what you actually meant :(
                          I'm also not sure where threading
                          comes into it particularly...
                          >
                          It just comes in the sense that you wouldn't like your data collection
                          being modified while reading. In case of "reference by value" that's not
                          a problem cos it never gets updated anyway - just remains stuck with an
                          old collection unless you do something on your own, lol.
                          No, the collection itself can be changed without changing which
                          collection the variable refers to.
                          Imagine a class which handles rendering at 15 frames a second. Now,
                          imagine that you have a collection of objects it renders to screen or
                          wherever you fancy. Do you really desire to inform the class that some
                          objects are added/removed from the data collection? I'd rather have a
                          memory-wise reference that assures the class would always see the
                          updated collection. What's the point in copying reference values of
                          let's say 1000 objects 15 times a second (provided collection changes so
                          dynamically)?
                          Um, you will. You can change the contents of the array or another
                          collection. Here's a short example:

                          using System;

                          class Foo
                          {
                          string[] names;

                          public Foo(string[] names)
                          {
                          this.names = names;
                          }

                          public void ShowNames()
                          {
                          Console.WriteLi ne("Names:");
                          foreach (string name in names)
                          {
                          Console.WriteLi ne(name);
                          }
                          }
                          }

                          class Test
                          {
                          static void Main()
                          {
                          string[] x = {"Jon", "Holly"};
                          Foo foo = new Foo(x);
                          foo.ShowNames() ;
                          x[0] = "Robin";
                          x[1] = "William";
                          foo.ShowNames() ;
                          }
                          }

                          The changes (made in Test) to the array are visible in Foo, because
                          they both share a reference to the same array. The same would be true
                          for other reference types such as List<T>.

                          Now in the display updating example you'd need to potentially be
                          careful with threading, yes - but it's not too bad a problem.

                          Given how the above works, why would I want to use "ref" in the
                          constructor signature? Bear in mind that the "ref" would only affect
                          the parameter itself anyway...

                          Jon

                          Comment

                          • A n g l e r

                            #14
                            Re: Inheritance of constructors.

                            class Test
                            {
                            static void Main()
                            {
                            string[] x = {"Jon", "Holly"};
                            Foo foo = new Foo(x);
                            foo.ShowNames() ;
                            x[0] = "Robin";
                            x[1] = "William";
                            foo.ShowNames() ;
                            }
                            }
                            And what now happens if you wanted to add yet another field? You'd have
                            to write x = {"bla", "bla", "bla"} which results in a new reference by
                            value that isn't passed to Foo. OK, you may go for some more advanced
                            container of objects where you can add/delete all stuff by appropriate
                            methods, though this suddenly becomes more and more elaborate while with
                            means of memory-wise reference you could replace the whole array easily
                            if needed.

                            Comment

                            • Jon Skeet [C# MVP]

                              #15
                              Re: Inheritance of constructors.

                              A n g l e r <p|k|o|n|i|u|s| z@h-o-t-m-a-i-l.c_o_mwrote:
                              class Test
                              {
                              static void Main()
                              {
                              string[] x = {"Jon", "Holly"};
                              Foo foo = new Foo(x);
                              foo.ShowNames() ;
                              x[0] = "Robin";
                              x[1] = "William";
                              foo.ShowNames() ;
                              }
                              }
                              >
                              And what now happens if you wanted to add yet another field?
                              You can't with an array. You could with other collections such as
                              List<T>.
                              You'd have to write x = {"bla", "bla", "bla"} which results in a new
                              reference by value that isn't passed to Foo. OK, you may go for some
                              more advanced container of objects where you can add/delete all stuff
                              by appropriate methods, though this suddenly becomes more and more
                              elaborate while with means of memory-wise reference you could replace
                              the whole array easily if needed.
                              Using List<Tis hardly elaborate, and it results in a nice simple
                              model. The complexity is hidden in the container, instead of having to
                              keep track of where a reference originally came from (and making sure
                              that's not inappropriately on a stack somewhere, ready to pop out of
                              existence...)

                              --
                              Jon Skeet - <skeet@pobox.co m>
                              Web site: http://www.pobox.com/~skeet
                              Blog: http://www.msmvps.com/jon_skeet
                              C# in Depth: http://csharpindepth.com

                              Comment

                              Working...