Initialize class fields in constructor or at declaration?

前端 未结 15 2070
南旧
南旧 2020-11-22 01:16

I\'ve been programming in C# and Java recently and I am curious where the best place is to initialize my class fields.

Should I do it at declaration?:



        
相关标签:
15条回答
  • 2020-11-22 02:00

    Not a direct answer to your question about the best practice but an important and related refresher point is that in the case of a generic class definition, either leave it on compiler to initialize with default values or we have to use a special method to initialize fields to their default values (if that is absolute necessary for code readability).

    class MyGeneric<T>
    {
        T data;
        //T data = ""; // <-- ERROR
        //T data = 0; // <-- ERROR
        //T data = null; // <-- ERROR        
    
        public MyGeneric()
        {
            // All of the above errors would be errors here in constructor as well
        }
    }
    

    And the special method to initialize a generic field to its default value is the following:

    class MyGeneric<T>
    {
        T data = default(T);
    
        public MyGeneric()
        {           
            // The same method can be used here in constructor
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:05

    Being consistent is important, but this is the question to ask yourself: "Do I have a constructor for anything else?"

    Typically, I am creating models for data transfers that the class itself does nothing except work as housing for variables.

    In these scenarios, I usually don't have any methods or constructors. It would feel silly to me to create a constructor for the exclusive purpose of initializing my lists, especially since I can initialize them in-line with the declaration.

    So as many others have said, it depends on your usage. Keep it simple, and don't make anything extra that you don't have to.

    0 讨论(0)
  • 2020-11-22 02:06

    My rules:

    1. Don't initialize with the default values in declaration (null, false, 0, 0.0…).
    2. Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
    3. If the value of the field changes because of a constructor parameter put the initialization in the constructors.
    4. Be consistent in your practice (the most important rule).
    0 讨论(0)
  • 2020-11-22 02:06

    The semantics of C# differs slightly from Java here. In C# assignment in declaration is performed before calling the superclass constructor. In Java it is done immediately after which allows 'this' to be used (particularly useful for anonymous inner classes), and means that the semantics of the two forms really do match.

    If you can, make the fields final.

    0 讨论(0)
  • 2020-11-22 02:08

    There are many and various situations.

    I just need an empty list

    The situation is clear. I just need to prepare my list and prevent an exception from being thrown when someone adds an item to the list.

    public class CsvFile
    {
        private List<CsvRow> lines = new List<CsvRow>();
    
        public CsvFile()
        {
        }
    }
    

    I know the values

    I exactly know what values I want to have by default or I need to use some other logic.

    public class AdminTeam
    {
        private List<string> usernames;
    
        public AdminTeam()
        {
             usernames = new List<string>() {"usernameA", "usernameB"};
        }
    }
    

    or

    public class AdminTeam
    {
        private List<string> usernames;
    
        public AdminTeam()
        {
             usernames = GetDefaultUsers(2);
        }
    }
    

    Empty list with possible values

    Sometimes I expect an empty list by default with a possibility of adding values through another constructor.

    public class AdminTeam
    {
        private List<string> usernames = new List<string>();
    
        public AdminTeam()
        {
        }
    
        public AdminTeam(List<string> admins)
        {
             admins.ForEach(x => usernames.Add(x));
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:13

    Assuming the type in your example, definitely prefer to initialize fields in the constructor. The exceptional cases are:

    • Fields in static classes/methods
    • Fields typed as static/final/et al

    I always think of the field listing at the top of a class as the table of contents (what is contained herein, not how it is used), and the constructor as the introduction. Methods of course are chapters.

    0 讨论(0)
提交回复
热议问题