浅尝EffectiveCSharp_7

Item 14: Minimize Duplicate Initialization Logic  最小化重复的初始化逻辑

  • 写构造器经常是一种重复的工作。许多人写好第一个构造器后,用复制、粘贴到另一个构造器,来满足对类的重载。从现在起,不要在这样做,当你发现多种构造器拥有相同的逻辑时,把相同的逻辑提炼出来,放到一个公共的构造器中。你会体验到防止代码重复的好处。而编译器也最小化的执行代码,构造器允许一个构造器去访问另一个构造器
    public class MyClass
    {
      // collection of data
      private List<ImportantData> coll;
      // Name of the instance:
      private string name;
      public MyClass() :
        this(0, "")
      {
      }
      public MyClass(int initialCount) :
        this(initialCount, string.Empty)
      {
      }
      public MyClass(int initialCount, string name)
      {
        coll
    = (initialCount > 0) ?
        new List<ImportantData>(initialCount) :
        new List<ImportantData>();
        this.name = name;
      }
    }
  • C#4.0增加了默认参数,这样你就能最小化构造函数中的重复代码。 C# 4.0 adds default parameters, which you can use to minimize the duplicated
    code in constructors. You could replace all the different constructors for MyClass with one constructor that specifies default values for all or many of the values:

    public class MyClass
    {
      // collection of data
      private List<ImportantData> coll;
      // Name of the instance:
      private string name;
      // Needed to satisfy the new() constraint.
      public MyClass() :
        this(0, string.Empty)
      {
      }
      public MyClass(int initialCount = 0, string name = "")
      {
        coll
    = (initialCount > 0) ?
        new List<ImportantData>(initialCount) :
        new List<ImportantData>();
        this.name = name;
      }
    }

     在选择默认参数还是重载上我们要做权衡(see item 10)。There are tradeoffs in choosing default parameters over using multiple overloads.默认参数为用户创造了更多的选择。上面的Myclass为两个参数都指定了默认值。用户可以为参数(either or both)指定不同的值。如果考虑所有的情况,重载的方式需要4个不同的构造器。而且,随着参数的增加,重载数量也会增加。这种复杂性也让默认参数有了更好的途径,来最小化潜在的重载数量。

  • 为所有类型的构造器定义默认值意味着,当调用new MyClass()时要有清晰的代码。Defining default values for all parameters to your type’s constructor means that user code will be valid when you call the new MyClass().当你想使用这种方法,你需要创建一个无参的构造器(就像上面的例子)。尽管多数的代码可以使用默认参数,但是一般使用new()方法的类不会接受都是默认参数的构造函数,因此,一个类需要有一个无参的构造器。

  • 你可能发现在第二个构造器中,为name参数指定""为默认值,而不是通常的string.Empty。这是因为string.Empty不是一个“编译时”常量。它是一个string类中的静态属性。

  • 从C#版本1.0到3.5都没有支持默认参数。那时候,你一定会使用一个构造器调用另一个构造器的函数链方式,来代替创建一个公用的方法。

    public class MyClass
    {
      // collection of data
      private List<ImportantData> coll;
      // Name of the instance:
      private string name;
      public MyClass()
      {
        commonConstructor(
    0, "");
      }  
      public MyClass(int initialCount)
      {
        commonConstructor(initialCount,
    "");
      }
      public MyClass(int initialCount, string Name)
      {
        commonConstructor(initialCount, Name);
      }
      private void commonConstructor(int count,string name)
      {
        coll
    = (count > 0) ?
            new List<ImportantData>(count) :
            new List<ImportantData>();
        this.name = name;
      }
    }

     这个版本看起来差不多,但是它是低效的。编译器步伐从你写的公共方法中提取重复的代码。

  • 默认函数和重载都有他们使用的地方。总之,你应该尽量使用默认参数,而不是构造器重载。Both default parameters and overloads have their place. In general, you should prefer default values to overloaded constructors.

  • This is the last item about object initialization in C#. Here is the order of operations for constructing the first instance of a type:

    1. Static variable storage is set to 0.
    2. Static variable initializers execute.
    3. Static constructors for the base class execute.
    4. The static constructor executes.
    5. Instance variable storage is set to 0.
    6. Instance variable initializers execute.
    7. The appropriate base class instance constructor executes.
    8. The instance constructor executes.
原文地址:https://www.cnblogs.com/TivonStone/p/1754595.html