在构造函数中实例化对象 [英] Instantiating objects in the constructor

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

问题描述

执行以下操作是否有好处:

public class Foo
{
    private Bar bar;

    public Foo()
    {
        bar = new Bar();
    }
}

与其那样做:

public class Foo
{
    private Bar bar = new Bar();

    public Foo()
    {
    }
}

鉴于实例化时,两个示例中的private成员变量都将被实例化,我不相信有什么区别,但是我已经好奇地看到了很多次.

解决方案

在您所给出的确切情况下,没有什么区别,但总的来说是有区别的.

在初始化基类构造函数之前,先执行变量初始化程序.如果该基本构造函数调用使用某些实例变量的虚拟方法,则可以看到这种差异.

对于规范迷,它在C#4规范的10.11.2节中:

当实例构造函数没有构造函数初始值设定项,或者它具有base(...)形式的构造函数初始值设定项时,该构造函数将隐式执行由其类中声明的实例字段的变量初始值设定项指定的初始化.这对应于分配的序列,这些分配的序列在进入构造函数后即在隐式调用直接基类构造函数之前立即执行.

下面是一个演示此情况的示例:

using System;

public class Base
{
    public Base()
    {
        Dump();
    }

    public virtual void Dump() {}    
}

class Child : Base
{
    private string x = "initialized in declaration";
    private string y;

    public Child()
    {
        y = "initialized in constructor";
    }

    public override void Dump()
    {
        Console.WriteLine("x={0}; y={1}", x, y);
    }
}

class Test
{
    static void Main(string[] args)
    {
        new Child();
    }
}

结果:

x =在声明中初始化; y =

现在已经说完了,我将尽力避免从构造函数中调用虚方法.您基本上是在要求派生类以部分初始化的方式工作.但是,您应该意识到这是不同的.

关于 where 来初始化变量...我必须承认我不是特别一致,而且我认为这实际上不是问题.如果我有任何特定的偏见,可能是要在声明时初始化不依赖于任何参数的任何内容,而将我无法初始化的变量留给构造函数. /p>

Is there any benefit to doing the following:

public class Foo
{
    private Bar bar;

    public Foo()
    {
        bar = new Bar();
    }
}

Instead of doing it like so:

public class Foo
{
    private Bar bar = new Bar();

    public Foo()
    {
    }
}

Given that at instantiation, the private member variable in either example will be instantiated, I don't believe there is a difference, but I've seen it enough times to where I'm curious.

解决方案

In the exact case you've given, there isn't a difference - but in general there is.

Variable initializers are executed before the base class constructor is called. If that base constructor calls a virtual method which uses some of the instance variables, you can see that difference.

For spec fans, it's in section 10.11.2 of the C# 4 spec:

When an instance constructor has no constructor initializer, or it has a constructor initializer of the form base(...), that constructor implicitly performs the initializations specified by the variable-initializers of the instance fields declared in its class. This corresponds to a sequence of assignments that are executed immediately upon entry to the constructor and before the implicit invocation of the direct base class constructor.

Here's an example demonstrating this:

using System;

public class Base
{
    public Base()
    {
        Dump();
    }

    public virtual void Dump() {}    
}

class Child : Base
{
    private string x = "initialized in declaration";
    private string y;

    public Child()
    {
        y = "initialized in constructor";
    }

    public override void Dump()
    {
        Console.WriteLine("x={0}; y={1}", x, y);
    }
}

class Test
{
    static void Main(string[] args)
    {
        new Child();
    }
}

Result:

x=initialized in declaration; y=

Now having said the above, I would try hard to avoid calling virtual methods from a constructor. You're basically asking the derived class to work in a partially-initialized fashion. However, it's a difference you should be aware of.

As for where to initialize variables... I have to admit I'm not particularly consistent, and I don't find that's actually a problem. If I have any specific bias, it's probably to initialize anything which won't depend on any parameters at the point of declaration, leaving the variables which I can't initialize without extra information to the constructor.

这篇关于在构造函数中实例化对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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