在字段定义或类构造函数中初始化类字段 [英] Initializing Class Fields at the Field Definition or in Class Constructor

查看:190
本文介绍了在字段定义或类构造函数中初始化类字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class with a field that needs to be initialized when the object is initialized, such as a list that needs to be created before objects can be added/removed from it.

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()
    {
    }
}


b $ b

这两个类之间有什么区别,为什么要选择一个方法呢?

What is the difference between these two classes, and why would you choose one method over the other?

我通常在构造函数中设置字段,如在MyClass1中,因为我发现更容易在一个地方查看所有的东西,当对象被实例化时发生,但是有没有更好地初始化一个字段直接像MyClass2? / p>

I usually set the field in the constructor, as in MyClass1, because I find it easier to be able to look in one place to see all the stuff that happens when the object is being instantiated, but is there any case where it is better to initialize a field directly like in MyClass2?

推荐答案

C#编译器(VS2008 sp1)发出的ILs几乎相当于两种情况(即使在Debug和Release版本中)。

The ILs emitted by C# compiler (VS2008 sp1) will be almost equivalent for both cases (even in Debug and Release builds).

但是,如果您 需要添加参数化构造函数 ; MyOtherClass> 作为参数 ,它会有所不同(尤其是当你将创建大量的对象时,这样的构造函数)。

However, if you need to add parameterized constructors that take List<MyOtherClass> as an argument, it will be different (especially, when you will create a significantly large number of objects with such constructors).

查看以下示例以了解差异(您可以复制并过渡到VS,并使用 Reflector ILDASM)。

See the following examples to see the differences (you can copy&past to VS and build it to see ILs with Reflector or ILDASM).

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();
        }
    }
}

/ strong>切换到发布版本时,我没有更改任何优化标志。

Note: I did not change any optimization flag when switching to Release build.

这篇关于在字段定义或类构造函数中初始化类字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆