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. Philisophical question

Philisophical question

Scheduled Pinned Locked Moved C#
questioncsharpvisual-studio
17 Posts 7 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.
  • G Offline
    G Offline
    Gary Wheeler
    wrote on last edited by
    #1

    There are two ways to initialize members in a C# class, via constructor:

    class MyClass
    {
    private int Member;
    public MyClass()
    {
    Member = 0;
    }
    }

    or through member initialization:

    class MyClass
    {
    private int Member = 0;
    }

    My question: Are there problems / benefits of one approach vs. another? From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

    Software Zen: delete this;

    D realJSOPR S S V 5 Replies Last reply
    0
    • G Gary Wheeler

      There are two ways to initialize members in a C# class, via constructor:

      class MyClass
      {
      private int Member;
      public MyClass()
      {
      Member = 0;
      }
      }

      or through member initialization:

      class MyClass
      {
      private int Member = 0;
      }

      My question: Are there problems / benefits of one approach vs. another? From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

      Software Zen: delete this;

      D Offline
      D Offline
      Douglas Troy
      wrote on last edited by
      #2

      Gary, If the class calls Finalize, then using member initialization is certainly the right way to go. The reason being, if there is an error in the constructor, and Finalize is called, then the state of the fields could come into play. Using member initialization in this case means that you know your fields are valid, so you won't have issues if finalize is called following failed object construction. D.


      Last modified: 12mins after originally posted --

      S 1 Reply Last reply
      0
      • G Gary Wheeler

        There are two ways to initialize members in a C# class, via constructor:

        class MyClass
        {
        private int Member;
        public MyClass()
        {
        Member = 0;
        }
        }

        or through member initialization:

        class MyClass
        {
        private int Member = 0;
        }

        My question: Are there problems / benefits of one approach vs. another? From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

        Software Zen: delete this;

        realJSOPR Online
        realJSOPR Online
        realJSOP
        wrote on last edited by
        #3

        FXCop will trigger an "issue" if you do the 2nd thing, but FXCop is, after all, just a style guide and most of what it chokes/pukes on can safely be ignored. I tend to use method #2 in your examples.

        "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
        -----
        "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

        1 Reply Last reply
        0
        • G Gary Wheeler

          There are two ways to initialize members in a C# class, via constructor:

          class MyClass
          {
          private int Member;
          public MyClass()
          {
          Member = 0;
          }
          }

          or through member initialization:

          class MyClass
          {
          private int Member = 0;
          }

          My question: Are there problems / benefits of one approach vs. another? From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

          Software Zen: delete this;

          S Offline
          S Offline
          Scott Dorman
          wrote on last edited by
          #4

          I don't think it really matters, especially in the case of setting variables to their default values (which is recommended to not do). If you have multiple constructors, you can set the initial values in your simplest constructor and then use constructor chaining. In your first example, you actually end up with 3 additional lines of IL in the constructor to handle loading the arguement on to the evaluation stack (which it already does), then loading the 0 as an integer on to the evaluation stack, and then replacing the value stored in the "Member" field with the new value.

          Scott Dorman

          Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


          Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

          C G 2 Replies Last reply
          0
          • S Scott Dorman

            I don't think it really matters, especially in the case of setting variables to their default values (which is recommended to not do). If you have multiple constructors, you can set the initial values in your simplest constructor and then use constructor chaining. In your first example, you actually end up with 3 additional lines of IL in the constructor to handle loading the arguement on to the evaluation stack (which it already does), then loading the 0 as an integer on to the evaluation stack, and then replacing the value stored in the "Member" field with the new value.

            Scott Dorman

            Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


            Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

            C Offline
            C Offline
            carbon_golem
            wrote on last edited by
            #5

            Right. Also if initialization of any kind is put into the body of the class, it will be injected into every constructor when compiled to IL so it will tend to bloat up classes with multiple constructors. If you're a real performance nazi you'd have to take nuggets like that into consideration because the JITer will inline code under 32 bytes. See Here. Scott P.

            "Simplicity carried to the extreme becomes elegance."
            -Jon Franklin

            S S 2 Replies Last reply
            0
            • C carbon_golem

              Right. Also if initialization of any kind is put into the body of the class, it will be injected into every constructor when compiled to IL so it will tend to bloat up classes with multiple constructors. If you're a real performance nazi you'd have to take nuggets like that into consideration because the JITer will inline code under 32 bytes. See Here. Scott P.

              "Simplicity carried to the extreme becomes elegance."
              -Jon Franklin

              S Offline
              S Offline
              Scott Dorman
              wrote on last edited by
              #6

              carbon_golem wrote:

              JITer will inline code under 32 bytes.

              Great point.

              Scott Dorman

              Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


              Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

              1 Reply Last reply
              0
              • C carbon_golem

                Right. Also if initialization of any kind is put into the body of the class, it will be injected into every constructor when compiled to IL so it will tend to bloat up classes with multiple constructors. If you're a real performance nazi you'd have to take nuggets like that into consideration because the JITer will inline code under 32 bytes. See Here. Scott P.

                "Simplicity carried to the extreme becomes elegance."
                -Jon Franklin

                S Offline
                S Offline
                S Senthil Kumar
                wrote on last edited by
                #7

                carbon_golem wrote:

                it will be injected into every constructor when compiled to IL so it will tend to bloat up classes with multiple constructors.

                Even if the constructors are chained with this(...)?

                Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

                C 1 Reply Last reply
                0
                • G Gary Wheeler

                  There are two ways to initialize members in a C# class, via constructor:

                  class MyClass
                  {
                  private int Member;
                  public MyClass()
                  {
                  Member = 0;
                  }
                  }

                  or through member initialization:

                  class MyClass
                  {
                  private int Member = 0;
                  }

                  My question: Are there problems / benefits of one approach vs. another? From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

                  Software Zen: delete this;

                  S Offline
                  S Offline
                  S Senthil Kumar
                  wrote on last edited by
                  #8

                  There's a subtle difference if you call virtual methods from your constructor, which is generally not advisable. When generating IL code for the constructor, the C# compiler puts code for all field initializers before code for the constructor's body This means that overridden will see initialized values for field initialized members, but will see default values for others.

                  class Base
                  {
                  protected int x = 42;
                  protected int y;

                  public Base()
                  {
                  SomeVirtualMethod();
                  y = 42;
                  }

                  protected virtual void SomeVirtualMethod() {}
                  }

                  class Derived : Base
                  {
                  protected override void SomeVirtualMethod()
                  {
                  Console.WriteLine(x);
                  Console.WriteLine(y);
                  }
                  }

                  prints 42 and 0.

                  Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

                  1 Reply Last reply
                  0
                  • G Gary Wheeler

                    There are two ways to initialize members in a C# class, via constructor:

                    class MyClass
                    {
                    private int Member;
                    public MyClass()
                    {
                    Member = 0;
                    }
                    }

                    or through member initialization:

                    class MyClass
                    {
                    private int Member = 0;
                    }

                    My question: Are there problems / benefits of one approach vs. another? From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

                    Software Zen: delete this;

                    V Offline
                    V Offline
                    Vikram A Punathambekar
                    wrote on last edited by
                    #9

                    Gary, in your case, this will do:

                    class MyClass
                    {
                    private int Member;
                    }

                    Class level members are always initialized to default values. Strings are empty, numbers are 0, and bools are false.

                    Cheers, Vıkram.


                    I don't suffer from insanity, I enjoy every moment of it.

                    G 1 Reply Last reply
                    0
                    • V Vikram A Punathambekar

                      Gary, in your case, this will do:

                      class MyClass
                      {
                      private int Member;
                      }

                      Class level members are always initialized to default values. Strings are empty, numbers are 0, and bools are false.

                      Cheers, Vıkram.


                      I don't suffer from insanity, I enjoy every moment of it.

                      G Offline
                      G Offline
                      Gary Wheeler
                      wrote on last edited by
                      #10

                      I'm afraid my example was a little contrived. The actual code involved is a socket interface to a set of services. The interface includes a number of data structures that have to be initialized prior to startup, and it seemed stupid to duplicate the logic (or at least the method call to the logic) in every constructor.

                      Software Zen: delete this;

                      V 1 Reply Last reply
                      0
                      • S Scott Dorman

                        I don't think it really matters, especially in the case of setting variables to their default values (which is recommended to not do). If you have multiple constructors, you can set the initial values in your simplest constructor and then use constructor chaining. In your first example, you actually end up with 3 additional lines of IL in the constructor to handle loading the arguement on to the evaluation stack (which it already does), then loading the 0 as an integer on to the evaluation stack, and then replacing the value stored in the "Member" field with the new value.

                        Scott Dorman

                        Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                        Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                        G Offline
                        G Offline
                        Gary Wheeler
                        wrote on last edited by
                        #11

                        I do use constructor chaining occasionally, where it's appropriate. My concern here is duplicating logic in each constructor, when the member initialization takes care of it in one place. Since I'm new to .NET, I was concerned there was some drawback to using member initialization that I wasn't aware of.

                        Software Zen: delete this;

                        S 1 Reply Last reply
                        0
                        • G Gary Wheeler

                          I'm afraid my example was a little contrived. The actual code involved is a socket interface to a set of services. The interface includes a number of data structures that have to be initialized prior to startup, and it seemed stupid to duplicate the logic (or at least the method call to the logic) in every constructor.

                          Software Zen: delete this;

                          V Offline
                          V Offline
                          Vikram A Punathambekar
                          wrote on last edited by
                          #12

                          Ah, apologies, I didn't know that. But you have got some excellent answers :) I learnt some bits myself, so thanks for posting the question.

                          Cheers, Vıkram.


                          I don't suffer from insanity, I enjoy every moment of it.

                          G 1 Reply Last reply
                          0
                          • V Vikram A Punathambekar

                            Ah, apologies, I didn't know that. But you have got some excellent answers :) I learnt some bits myself, so thanks for posting the question.

                            Cheers, Vıkram.


                            I don't suffer from insanity, I enjoy every moment of it.

                            G Offline
                            G Offline
                            Gary Wheeler
                            wrote on last edited by
                            #13

                            No need to apologize, Vikram; thanks for answering.

                            Software Zen: delete this;

                            1 Reply Last reply
                            0
                            • G Gary Wheeler

                              I do use constructor chaining occasionally, where it's appropriate. My concern here is duplicating logic in each constructor, when the member initialization takes care of it in one place. Since I'm new to .NET, I was concerned there was some drawback to using member initialization that I wasn't aware of.

                              Software Zen: delete this;

                              S Offline
                              S Offline
                              Scott Dorman
                              wrote on last edited by
                              #14

                              I understand the concern, but you can still keep the member initialization in one place in your simplest constructor. For example:

                              public class Class1
                              {
                              private int count;
                              private string status;
                              private bool flag;

                              public Class1()
                              {
                              this.count = 1;
                              this.status = "None";
                              }

                              public Class1() : this()
                              {
                              flag = false;
                              }

                              Scott Dorman

                              Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                              Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                              1 Reply Last reply
                              0
                              • D Douglas Troy

                                Gary, If the class calls Finalize, then using member initialization is certainly the right way to go. The reason being, if there is an error in the constructor, and Finalize is called, then the state of the fields could come into play. Using member initialization in this case means that you know your fields are valid, so you won't have issues if finalize is called following failed object construction. D.


                                Last modified: 12mins after originally posted --

                                S Offline
                                S Offline
                                S Senthil Kumar
                                wrote on last edited by
                                #15

                                Douglas Troy wrote:

                                Using member initialization in this case means that you know your fields are valid, so you won't have issues if finalize is called following failed object construction.

                                How so?

                                    static class Win32
                                    {
                                        public static IntPtr OpenHandle() { return IntPtr.Zero; }
                                        public static void CloseHandle(IntPtr ptr) { }
                                    }
                                
                                    class TestClass
                                    {
                                        IntPtr h1 = Win32.OpenHandle();
                                
                                        ~TestClass()
                                        {
                                            Win32.CloseHandle(h1);
                                        }
                                    }
                                

                                If OpenHandle throws an exception, I would expect the finalizer to still run, with h1 having the default value.

                                Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

                                1 Reply Last reply
                                0
                                • S S Senthil Kumar

                                  carbon_golem wrote:

                                  it will be injected into every constructor when compiled to IL so it will tend to bloat up classes with multiple constructors.

                                  Even if the constructors are chained with this(...)?

                                  Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

                                  C Offline
                                  C Offline
                                  carbon_golem
                                  wrote on last edited by
                                  #16

                                  No. If you chain constructors, the compiler is smart enough to put members initialized in the class body into the last chain target. I went back through and verified this. Here is some sample code for you to compile and run ILDasm on. Car has chained constructors, where Truck does not. Truck's constructors all get the initialization code for the CultureInfo member, where Car has the initialization for CultureInfo in the constructor that takes 2 args. using System; using System.Globalization; namespace ConstructorChainKata { class Program { static void Main(string[] args) { } } public enum Market { Production, Concept, Military, Custom, Armored } public class Car { private String manufacturer; private Market market; private CultureInfo targetLocale = new CultureInfo("en-US"); public Car(String manuf) :this(manuf, Market.Production) { //.. } public Car(String manuf, Market markt) { manufacturer = manuf; market = markt; } } public class Truck { private String manufacturer; private Market market; private CultureInfo targetLocale = new CultureInfo("en-US"); public Truck(String manuf) { manufacturer = manuf; market = Market.Production; } public Truck(String manuf, Market markt) { manufacturer = manuf; market = markt; } } } Scott P

                                  "Simplicity carried to the extreme becomes elegance."
                                  -Jon Franklin

                                  S 1 Reply Last reply
                                  0
                                  • C carbon_golem

                                    No. If you chain constructors, the compiler is smart enough to put members initialized in the class body into the last chain target. I went back through and verified this. Here is some sample code for you to compile and run ILDasm on. Car has chained constructors, where Truck does not. Truck's constructors all get the initialization code for the CultureInfo member, where Car has the initialization for CultureInfo in the constructor that takes 2 args. using System; using System.Globalization; namespace ConstructorChainKata { class Program { static void Main(string[] args) { } } public enum Market { Production, Concept, Military, Custom, Armored } public class Car { private String manufacturer; private Market market; private CultureInfo targetLocale = new CultureInfo("en-US"); public Car(String manuf) :this(manuf, Market.Production) { //.. } public Car(String manuf, Market markt) { manufacturer = manuf; market = markt; } } public class Truck { private String manufacturer; private Market market; private CultureInfo targetLocale = new CultureInfo("en-US"); public Truck(String manuf) { manufacturer = manuf; market = Market.Production; } public Truck(String manuf, Market markt) { manufacturer = manuf; market = markt; } } } Scott P

                                    "Simplicity carried to the extreme becomes elegance."
                                    -Jon Franklin

                                    S Offline
                                    S Offline
                                    S Senthil Kumar
                                    wrote on last edited by
                                    #17

                                    Yeah, that's what I thought it would do. In fact, if the compiler did not do this, the program would be wrong - field initializers would run as many times as the length of the chain. If some of the field initializers got populated as a result of a static method call with side effects...

                                    Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

                                    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