在字段定义或类构造函数中初始化类字段

Eri*_*tas 9 c# constructor field initialization

我有一个类,其中一个字段需要在初始化对象时初始化,例如需要在对象添加/删除之前创建的列表.

public class MyClass1
{
    private List<MyOtherClass> _otherClassList;

    public MyClass1()
    {
        this._otherClasslist = new List<MyOtherClass>();
    }
}


public class MyClass2
{
    private List<MyOtherClass> = new List<MyOtherClass>();

    public MyClass2()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这两个类有什么区别,为什么你会选择一种方法而不是另一种呢?

我通常在构造函数中设置字段,就像在MyClass1中一样,因为我发现更容易在一个地方查看以查看在实例化对象时发生的所有事情,但是在任何情况下都更好地对像在MyClass2中一样直接初始化一个字段?

Cha*_* Im 5

在两种情况下(即使在Debug和Release版本中),C#编译器(VS2008 sp1)发出的IL几乎都是等效的.

但是,如果需要添加 作为参数的参数化构造函数,它将会有所不同(特别是,当您使用此类构造函数创建大量对象时). List<MyOtherClass>

请参阅以下示例以查看差异(您可以复制并过去到VS并构建它以查看带有ReflectorILDASM的IL).

using System;
using System.Collections.Generic;

namespace Ctors
{
    //Tested with VS2008 SP1
    class A
    {
        //This will be executed before entering any constructor bodies...
        private List<string> myList = new List<string>();

        public A() { }

        //This will create an unused temp List<string> object 
        //in both Debug and Release build
        public A(List<string> list)
        {
            myList = list;
        }
    }

    class B
    {
        private List<string> myList;

        //ILs emitted by C# compiler are identicial to 
        //those of public A() in both Debug and Release build 
        public B()
        {
            myList = new List<string>();
        }

        //No garbage here
        public B(List<string> list)
        {
            myList = list;
        }
    }

    class C
    {

        private List<string> myList = null;
        //In Release build, this is identical to B(), 
        //In Debug build, ILs to initialize myList to null is inserted. 
        //So more ILs than B() in Debug build.  
        public C()
        {
            myList = new List<string>();
        }

        //This is identical to B(List<string> list) 
        //in both Debug and Release build. 
        public C(List<string> list)
        {
            myList = list;
        }
    }

    class D
    {
        //This will be executed before entering a try/catch block
        //in the default constructor
        private E myE = new E();
        public D()
        {
            try
            { }
            catch (NotImplementedException e)
            {
                //Cannot catch NotImplementedException thrown by E(). 
                Console.WriteLine("Can I catch here???");
            }
        }
    }

    public class E
    {
        public E()
        {
            throw new NotImplementedException();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //This will result in an unhandled exception. 
            //You may want to use try/catch block when constructing D objects.
            D myD = new D();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:切换到Release版本时,我没有更改任何优化标志.