C#结构文档:构造函数初始化器与"ref"和"out"参数的关系



在C#文档中,特别是在结构中,我发现了以下我无法理解的句子:

如果结构实例构造函数没有指定构造函数初始值设定项,则this变量对应于结构类型的out参数,并且与out参数类似,必须在构造函数返回的每个位置明确赋值(绝对赋值(。如果结构实例构造函数指定了构造函数初始值设定项,则this变量对应于结构类型的ref参数,并且与ref参数类似,这被认为是在进入构造函数体时明确分配的。

我想知道构造函数中的这个关键字与ref和out关键字之间的关系。

如果您不熟悉文档中使用的术语,这可能看起来有点复杂,但让我们循序渐进。

基本规则是:结构构造函数必须确保结构实例的所有字段都已初始化。没有例外。

同样与以下内容相关的是;构造函数初始化器";意味着您正在通过多个构造函数链接调用:

public YourStruct(...) : this(...)
^----+----^
|
+-- constructor initializer

供参考,outref参数到方法:

public void Test(out int x) { ... }
public void Test(ref int x) { ... }

意味着out int x参数必须在方法中完全初始化,并且在方法开始时被视为未分配。请参阅out参数修饰符文档以供参考。

ref int x参数被认为是在方法开始时分配的,方法可以更改它,但不必更改。有关详细信息,请参阅ref关键字。

所以,现在让我们来学习其余的文档。

如果您的构造函数没有构造函数初始值设定项,那么这意味着您的构造函数必须自己处理基本规则。这意味着它类似于方法的out参数,构造函数必须在返回之前完全初始化结构实例。

但是,如果确实有构造函数初始值设定项,则构造函数必须完全初始化结构实例,因此当您的构造函数开始执行时,该实例已经完全初始化。在这种情况下,构造函数不必再初始化所有字段,而是可以选择性地只更改所需的字段。这就是关于ref参数的含义。

让我举一个例子:

public struct X
{
public int A;
public int B;
public X(int a, int b)
{
// no constructor initializer, MUST initialize both A and B
A = a;
B = b;
}
}

但是:

public struct X
{
public int A;
public int B;
public X(int a)
: this(a, 0)
{
// constructor initializer, DOES NOT have to initialize anything
// you can, though, if you want to change B
B++;
}
public X(int a, int b)
{
// no constructor initializer, MUST initialize both A and B
A = a;
B = b;
}
}

因此,基本上,文件说明:

  • 如果没有构造函数初始值设定项,构造函数必须完全初始化this变量,类似于out参数的工作方式
  • 如果您确实有一个构造函数初始值设定项,那么构造函数不必做任何事情,您可以考虑类似于ref参数的this变量

最新更新