Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这些对象的实例化方式有什么不同?_C#_Asp.net_Object Initialization - Fatal编程技术网

C# 这些对象的实例化方式有什么不同?

C# 这些对象的实例化方式有什么不同?,c#,asp.net,object-initialization,C#,Asp.net,Object Initialization,以下两种情况的区别是什么: class Data { PersonDataContext persons = new PersonDataContext(); public Data() {} } 对 class Data { PersonDataContext persons; public Data() { persons = new PersonDataContext(); } } public partial clas

以下两种情况的区别是什么:

class Data
{
    PersonDataContext persons = new PersonDataContext();
    public Data() {}
}

class Data
{
    PersonDataContext persons;
    public Data() 
    {
        persons = new PersonDataContext();
    }
}
public partial class Data : System.Web.UI.Page
{
    PersonDataContext persons;
    protected void Page_Load(object sender, EventArgs e)
    {
        persons = new PersonDataContext();
    }
}
我在asp.net中有同样的问题:

public partial class Data : System.Web.UI.Page
{
    PersonDataContext persons = new PersonDataContext();
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

class Data
{
    PersonDataContext persons;
    public Data() 
    {
        persons = new PersonDataContext();
    }
}
public partial class Data : System.Web.UI.Page
{
    PersonDataContext persons;
    protected void Page_Load(object sender, EventArgs e)
    {
        persons = new PersonDataContext();
    }
}

在第一种情况下,在声明的位置初始化变量

在第二种方法中,在构造函数中初始化它


主要区别在于,如果有其他构造函数,并且忘记初始化或链接构造函数,则可以有一个未初始化的变量。

唯一的区别是对象的创建顺序。如果我记得清楚的话,字段初始值设定项在构造函数之前运行,所以如果构造函数引用了字段,那么它已经在那里了

但从99.9%的案例来看,你不会发现两者之间有什么不同。在大多数情况下,直接在其上初始化字段更安全,这样可以防止在多个构造函数或派生类以及复杂层次结构的情况下忘记它


通常,构造函数用于获取外部参数来填充无法使用字段初始值设定项的字段。

字段初始值设定项在构造函数调用之前运行。因此,在案例1中,
PersonDataContext
的对象将在构造函数调用之前创建

PersonDataContext persons = new PersonDataContext();
在第二种情况下,构造函数将首先执行,然后初始化字段

你可以做一个简单的测试

class PersonDataContext
{
    public PersonDataContext()
    {
        Console.WriteLine("In PersonDataContext Constructor");
    }
}
class Data
{
    PersonDataContext persons = new PersonDataContext();
    public Data() 
    {
        Console.WriteLine("In Data Contructor");
    }
}

class Data2
{
    PersonDataContext persons;
    public Data2() 
    {
        Console.WriteLine("In Data2 Constructor");
        persons = new PersonDataContext();
    }
}
然后在你的主要方法中

static void Main(string[] args)
{

    Data d1 = new Data();
    Data2 d2 = new Data2();
    Console.Read();
}
输出

在PersonDataContext构造函数//案例1中

在Data Constructor//案例1中

在Data2构造函数//案例2中

在PersonDataContext构造函数//案例2中



对于asp示例,在第一种情况下,您的字段在
页面加载
事件之前初始化,在第二种情况下,您的字段在
页面加载
事件

中初始化,如果您使用默认构造函数以外的构造函数进行对象初始化,则第二种情况下将有
未初始化的变量
-

Data data = new Data(5);
但是如果您
像这样链接参数化构造函数来调用默认构造函数
-

class Data
{
    PersonDataContext persons;
    public Data() 
    {
        persons = new PersonDataContext();
    }

    public Data(int a) : this()
    {

    }
}

变量
persons
将被初始化。

在第一个示例中,只要构造函数是唯一的构造函数,就没有有效的区别。如果添加其他构造函数,则需要确保它们都初始化“persons”字段

在ASP.NET示例中(对于第二个代码段),您正在初始化Page_Load方法中的“persons”字段,这意味着使用此字段的任何其他方法可能会发现它未初始化。(您是指页面加载,还是将其设置为构造函数…?)


底线是,如果“persons”字段始终需要非空,则初始化为字段初始化器更安全…

在第二个示例中,主要区别在于页面加载只是处理请求时调用的许多ASP.NET事件之一。因此,在页面加载之前引发的事件将无法访问/使用此字段,因为它尚未初始化


检查ASP.NET页面生命周期:

嗯,对于引用类型,初始化为默认值(T)的变量为空。在c#中,你不能让一个变量保持未初始化状态(那么容易)。这对我来说是一个很好的经验。字段初始化者直接就可以了,非常感谢。