Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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#_Constructor - Fatal编程技术网

C# 构造函数和类成员初始化之间的差异?

C# 构造函数和类成员初始化之间的差异?,c#,constructor,C#,Constructor,使用传递参数实例化时使用构造函数有什么区别: Customer Costomer1 = new Customer(100, Mark, 5000); 做同样的事情,但不向构造函数传递任何东西,只是实例化成员 Customer Costomer1 = new Customer() { ID = 100, Name = "Mark", Salary = 5000, }; 哪一个更好,在什么情况下它们是好的 如果我说构造函数是在实例化一个对象时需要做更多的工作,而成员初始化仅用于字段和属性的签名值

使用传递参数实例化时使用构造函数有什么区别:

Customer Costomer1 = new Customer(100, Mark, 5000);
做同样的事情,但不向构造函数传递任何东西,只是实例化成员

Customer Costomer1 = new Customer() { ID = 100, Name = "Mark", Salary = 5000, };
哪一个更好,在什么情况下它们是好的

如果我说构造函数是在实例化一个对象时需要做更多的工作,而成员初始化仅用于字段和属性的签名值,那么我是否正确


如果我理解正确,如果可以使用构造函数,为什么要对成员使用第二个case?

在第二个选项中,除非添加验证,否则可能会遗漏一个参数,并且实例不完整,而在第一个选项中,所有参数都是必需的,所以不可能有一个部分构造的对象

如果有多个参数,则第二个版本的可读性会更高,但如果使用C#4,则可以在第一个版本中使用命名参数


第二个版本的代码编写工作量较小,但第一个版本更容易获得正确的结果。

第一个版本要求您在构建对象时具有参数(或可选参数)。第二个选项允许您根据需要初始化对象的属性。如果不需要初始化属性,那么第二个选项是更好的方法

这是一个语法快捷方式(将调用默认构造函数)

等于下列各项

Customer Costomer1 = new Customer()
Costomer1.ID = 100;
Costomer1.Name = "Mark";
Costomer1.Salary = 5000;

他们俩基本上都做同样的事。如果你看它,你总是必须调用构造函数

第二个调用默认构造函数。然后,它负责设置变量。首先,初始化构造函数内的变量

在任何情况下,第一个都是您最好的、最重要的选择。最好让对象通过构造函数初始化变量。在第二个示例中,初始化由创建此对象的类的实现完成,这可能不会从类中产生您想要的正确结果

例如,在第二个示例中,我会:

  Customer Costomer1 = new Customer() { Name = "Mark", Salary = 5000, };
现在我没有ID。构造函数参数将强制实现者遵守它的规则。不管怎样,都不能忽略传递到构造函数中的变量,除非放入空变量(即“”)

当我想对构造函数不接受的赋值变量进行快速初始化时,您的第二个示例是最好的。基本上,据我所知(我可能大错特错),第二个是这样做的:

   Customer Costomer1 = new Customer();
   Customer1.ID = 100;
   Customer1.Name = "Mark";
   Customer1.Salary = 500;
把第二个例子想象成纯粹的速记

构造类时,必须考虑使该类工作的变量是什么。例如,客户不能没有ID,尽管他们可能没有定义的薪资。如果我没有在我的客户中错误地包含ID,比如说它是0,那么在使用对象时,您可能会有一些非常奇怪的行为

考虑一下这个场景

   Customer Costomer1 = new Customer();
   Customer1.ID = 100;
   Customer1.Name = "Mark";
   Customer1.Salary = 500;

   Customer Costomer2 = new Customer();
   Customer1.Name = "John";
   Customer1.Salary = 500;

   Customer Costomer3 = new Customer();
   Customer1.Name = "Eric";
   Customer1.Salary = 500;
现在,您有两个客户的ID号为0。虽然您可能错误地通过构造函数将此值设置为相同的值,但在构造函数中设置值会迫使您考虑ID号。

另一件事是,例如,当我把你的代码用于我的项目时。假设我正在使用您的代码扩展您已经编写的程序。我可能知道也可能不知道客户必须有身份证号码这一事实。或者,更可能的是,我忘记初始化名称和ID号。因此,您的整个系统现在可能会表现出奇怪的行为

但纯粹地说,出于经验,强迫自己或实现者设置某些变量将逻辑隐藏在一个位置。我不再需要长串的代码来初始化这个对象绝对需要的每个变量。通常情况下,规则是,你可以采用任何可以重复的逻辑,并将其放在一个地方

最后,但并非最不重要的一点是,您通常不希望像这样公开可写变量。也就是说,重要的变量不应该被篡改。使用构造函数,可以使用ID号初始化类,并将其作为私有变量隐藏在类中。这样,实现者无论如何都不能将ID号变形为其他内容。根据我的经验,这有助于阻止人们“热固定”变量,从而给他们带来一些他们无法正常处理的结果。这可能会导致程序中出现一些非常奇怪的行为

实际上,你可以两全其美。考虑这一点:

class MyClass
{
    private int someVariable;
    public int someOtherVariable;

    public MyClass(int myVar)
    {
        someVariable = myVar;
    }
}
和初始化:

MyClass c = new MyClass(5) { someOtherVariable = 10 };

我认为还需要注意的是,对象初始值设定项的语法本质上与调用构造函数,然后在新的LOC上分别设置每个属性相同。这意味着在属性赋值之前调用构造函数,而第一个方法是在构造函数内赋值。+1。关于命名参数,请注意——如果构造函数以类似于
MyObject(int row,int column,int count,int depth)
的方式结束,并且具有相同类型的字段序列,那么第二个版本就更容易获得正确的结果。我不同意总是在构造上设置参数。这样做——如果您在构造函数中使用变量进行任何操作,例如设置需要高级逻辑的状态,而这些高级逻辑并不总是使用的话——这可能会有点过头。在最简单的场景中,你真的只需要“require”参数,这些参数对于要使用的对象来说是“required”的。@Geek我这么做有点匆忙。我已更新代码以正常工作。至于只初始化必需的变量,您是正确的。但是,如果希望避免初始化某些变量,根据是否要使用,可以重载构造函数。我曾与几家图书馆合作过,包括cough、EXT.NET,它们抱怨没有
MyClass c = new MyClass(5) { someOtherVariable = 10 };