c#下面构造函数中的两个this关键字之间的区别是什么?

c#下面构造函数中的两个this关键字之间的区别是什么?,c#,constructor,this,C#,Constructor,This,我不明白以下几点: 在下面找到的代码中,VisualStudio告诉我,我可以通过删除构造函数中的第二个this关键字来简化代码 但是为什么我不能去掉第一个这个关键字呢? 这两个变量都是在构造函数之外的类中声明的,因此对于实例,这两个变量都将被“重写”* 如果我删除了这两个关键字,那么VS会抱怨第一个赋值是给同一个变量的,而不是第二个。 对我来说唯一明显的区别是第二个变量是数组,但我不明白这会有什么不同 *我怀疑这里的覆盖不是正确的术语 public class CelestialObject

我不明白以下几点: 在下面找到的代码中,VisualStudio告诉我,我可以通过删除构造函数中的第二个
this
关键字来简化代码

但是为什么我不能去掉第一个
这个
关键字呢?
这两个变量都是在构造函数之外的类中声明的,因此对于实例,这两个变量都将被“重写”*

如果我删除了这两个
关键字,那么VS会抱怨第一个赋值是给同一个变量的,而不是第二个。
对我来说唯一明显的区别是第二个变量是数组,但我不明白这会有什么不同

*我怀疑这里的覆盖不是正确的术语

public class CelestialObject {

    CelestialBody[] celestialBodies;
    int celestialBodyCount;

    public CelestialObject(int celestialBodyCount = 2) {
        this.celestialBodyCount = celestialBodyCount;
        this.celestialBodies = new CelestialBody[celestialBodyCount];
    }
}

区别在于您有一个名为
celestialBodyCount
的参数-这意味着在构造函数中,标识符
celestialBodyCount
引用该参数,因此要访问该字段,您必须使用
this
对其进行限定


您没有名为
celestialbodys
的参数(或其他局部变量),因此标识符已经引用了字段,而不需要任何限定。

您不能删除第一个
this
关键字,因为您有一个与字段同名的参数
celestialBodyCount

int celestialBodyCount; // The field

关键字用于指示该字段正在分配给。否则,参数优先于字段,如中所述:

。。。实体的范围可能包括引入包含同名实体的新声明空间的声明。这样的声明会导致原始实体被隐藏

然后:

通过嵌套进行名称隐藏可能是由于在名称空间中嵌套名称空间或类型、在类或结构中嵌套类型以及参数和局部变量声明的结果。

在这种情况下,参数
celestialBodyCount
隐藏成员
celestialBodyCount

当然,如果确实删除了
,编译器将给出以下警告:

Assignment made to same variable; did you mean to assign something else?

此警告几乎总是表示存在错误,应始终清除。

在此代码中,没有
关键字:

public CelestialObject(int celestialBodyCount = 2) 
{
    celestialBodyCount = celestialBodyCount;
    this.celestialBodies = new CelestialBody[celestialBodyCount];
}
Visual Studio说:“很抱歉,如果没有
this
关键字,参数中有一个
celestialBodyCount
,因此它将被分配给自身,因为它是具有该名称的封闭匹配变量。您确定这是您的意思吗?还是说类级别字段?”Visual Studio对您很友好,但编译器将继续将参数中的
celestialBodyCount
分配给它自己,而不会将其分配给类级别字段。所以要感谢VisualStudio,因为编译器不会提醒您

当您放置
this.celestialBodyCount
时,Visual Studio知道您正在将其分配给类级别字段


对于
this.celestialbody
,没有混淆,只有一个存在,因此它可以使用或不使用
this

您还可以为此功能添加一个“谢谢”,如果没有此功能,许多错误都会显示出来,因为您在类级别和方法体中都有
celestialBodyCount
。编写
以参考班级级别。如果您不编写
这个
,它将首先查看方法的范围。如果找不到任何内容,则会在类级别查找值。更好的命名约定是在字段开头使用下划线编写字段,如下所示
\u celestialbody
。这就是resharper的建议,我总是这么做。按照惯例,我们给字段命名如下。但是参数和局部变量的命名没有下划线。因此,您无需编写此
。谢谢,我们将研究命名约定和一些样式管理内容。确切地说,编译器不会询问,它只会使用参数,因为它是可用的“最接近”选项。
public CelestialObject(int celestialBodyCount = 2) 
{
    celestialBodyCount = celestialBodyCount;
    this.celestialBodies = new CelestialBody[celestialBodyCount];
}