简体   繁体   English

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

[英]c# What makes the difference between the two this keywords in the constructor below?

I don't understand the following: In the code found below, Visual Studio tells me, that I can simplify my code by deleting the second this keyword in the constructor. 我不明白以下内容:在下面的代码中,Visual Studio告诉我,我可以通过删除构造函数中的第二个this关键字来简化我的代码。

But why can't then I do away with the first this keyword? 但是,为什么不能那么我弄死第一this关键字? Both variables were declared outside the constructor, in the class, so both will be "overridden"* for the instance. 这两个变量都是在构造函数之外的类中声明的,因此对于实例,两者都将被“覆盖”*。

If I remove both this keywords, then VS will complain that the first assignment is made to same variable, but not for the second. 如果我删除这两个this关键字,然后VS会抱怨第一分配到同一个变量做出,而不是第二。 The only obvious difference to me is the second variable is an array, but I do not understand how would that make it any different? 对我来说唯一明显的区别是第二个变量是一个数组,但我不明白它会如何使它有所不同?

*I suspect override is not the correct term here. *我怀疑覆盖不是这里正确的术语。

public class CelestialObject {

    CelestialBody[] celestialBodies;
    int celestialBodyCount;

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

You cannot do away with the first this keyword because you have a parameter with the same name as your field celestialBodyCount : 你不能做掉与第一this关键字,因为你有相同的名称作为您的字段参数celestialBodyCount

int celestialBodyCount; // The field

And

public CelestialObject(int celestialBodyCount = 2) { // The parameter.

The this keyword is required to indicate that the field is being assigned to. 需要this关键字来指示该字段已分配给。 Otherwise the parameter takes precedence over the field, as explained in 3.7.1 Name hiding : 否则,该参数优先于该字段,如3.7.1名称隐藏中所述

... the scope of an entity may include declarations that introduce new declaration spaces containing entities of the same name. ......实体的范围可能包括引入包含同名实体的新申报空间的声明。 Such declarations cause the original entity to become hidden. 此类声明会导致原始实体隐藏。

And then 3.7.1.1 Hiding through nesting : 然后3.7.1.1隐藏嵌套

Name hiding through nesting can occur as a result of nesting namespaces or types within namespaces, as a result of nesting types within classes or structs, and as a result of parameter and local variable declarations. 由于在类或结构中嵌套类型以及作为参数和局部变量声明的结果,在命名空间内嵌套命名空间或类型的结果可能会发生通过嵌套隐藏的名称

In this case the parameter celestialBodyCount hides the member celestialBodyCount . 在这种情况下,参数celestialBodyCount隐藏成员celestialBodyCount

Of course, if you do remove the this the compiler will helpfully give you the following warning: 当然,如果删除this编译器会帮忙,给你以下警告:

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

This warning almost always indicates a bug and should always be cleaned up. 此警告几乎总是表示错误,应始终清理。

The difference is that you've got a parameter called celestialBodyCount - which means that within the constructor, the identifier celestialBodyCount refers to the parameter, so to access the field you have to qualify it with this . 所不同的是,你有一个名为参数celestialBodyCount -这意味着在构造函数中,标识符celestialBodyCount指参数,因此访问你有资格的字段中this

You don't have a parameter (or other local variable) called celestialBodies , so that identifier already refers to the field, without any qualification required. 您没有名为celestialBodies的参数(或其他局部变量),因此该标识符已引用该字段,无需任何限定条件。

In this code, without this keyword: 在此代码中,没有this关键字:

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

Visual Studio is saying: "I am sorry but without the this keyword there is a celestialBodyCount in the parameter so it will be assigned to itself since it is the closed matching variable with that name. Are you sure this is what you mean? Or do you mean the class level field?" Visual Studio说:“我很抱歉,但是没有this关键字,参数中有一个celestialBodyCount ,因此它将被分配给自己,因为它是具有该名称的封闭匹配变量。你确定这是你的意思吗?或者做你的意思是班级水平?“ Visual Studio is being friendly to you but the compiler will go ahead and assign celestialBodyCount in the parameter to itself and it will not assign it to your class level field. Visual Studio对您很友好,但编译器会继续将参数中的celestialBodyCount分配给它自己,并且不会将它分配给您的类级别字段。 So be thankful to Visual Studio because the compiler will not remind you. 所以要感谢Visual Studio,因为编译器不会提醒您。

When you put this.celestialBodyCount then Visual Studio knows knows you are assigning it to the class level field. 当你this.celestialBodyCount Visual Studio知道你知道你正在将它分配给类级别字段。

For this.celestialBodies , there is no confusion, only one exists so it will work with or without this . 对于this.celestialBodies ,没有混淆,只有一个存在,所以它可以使用或不使用this

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM