我们何时使用" this"关键字?
我很好奇其他人如何使用此关键字。我倾向于在构造函数中使用它,但是我也可以在整个类中以其他方法使用它。一些例子:
在构造函数中:
public Light(Vector v) { this.dir = new Vector(v); }
别处
public void SomeMethod() { Vector vec = new Vector(); double d = (vec * vec) - (this.radius * this.radius); }
解决方案
回答
我每次引用实例变量时都使用它,即使我不需要。我认为这使代码更清晰。
回答
我在可能存在歧义的地方(显然)使用它。不只是编译器含糊(在这种情况下是必需的),而且对于查看代码的人也含糊。
回答
我倾向于用_来强调字段,因此实际上根本不需要使用它。还可以通过Rtends重构它们...
回答
我们应该始终使用它,我用它来区分私有字段和参数(因为我们的命名约定指出,我们不对成员和参数名称使用前缀(并且前缀是基于Internet上的信息,因此我认为最佳实践))
回答
我仅在绝对必要时使用它,即当另一个变量遮盖另一个变量时使用。如这里:
class Vector3 { float x; float y; float z; public Vector3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } }
或者正如Ryan Fox指出的,何时需要将此作为参数传递。 (局部变量优先于成员变量)
回答
任何时候我们都需要引用当前对象。
一个特别方便的场景是当对象正在调用函数并希望将其自身传递给该函数时。
例子:
void onChange() { screen.draw(this); }
回答
我几乎只在从相同类型内部引用类型属性时才使用此属性。正如另一个用户提到的那样,我还对本地字段加了下划线,因此不需要它们就可以引起注意。
回答
这取决于我正在使用的编码标准。如果我们使用_表示实例变量,则" this"将变得多余。如果我们不使用_,那么我倾向于使用它来表示实例变量。
回答
我也倾向于在所有地方都使用它,只是为了确保清楚地表明它是我们正在处理的实例成员。
回答
我无法相信所有说使用它的人总是"最佳实践"之类的。
如果存在歧义(例如在Corey的示例中)或者需要将对象作为参数传递(例如在Ryan的示例中),请使用" this"。否则就没有理由使用它,因为能够基于范围链解析变量应该足够清楚,以至于不需要限定变量。
编辑:在" this"上的Cdocumentation指示除了我提到的两个之外,还有更多用途用于声明索引器的" this"关键字
编辑:@Juan:h,我没有在语句中看到任何不一致之处,当我使用" this"关键字(如Cdocumentation中所记录)时,有3个实例,而这些都是我们真正需要它的时候。在没有任何阴影的情况下,在构造函数中的变量前面加上" this"仅是浪费击键,也浪费了我的阅读时间,这没有任何好处。
回答
绝不。曾经。如果我们具有可变的阴影,则命名约定将大打折扣。我的意思是,真的,没有区分成员变量的命名吗? Facepalm
回答
只要StyleCop告诉我,我都会使用它。必须遵守StyleCop。哦是的。
回答
我并不是说听起来很,但这没关系。
严重地。
查看重要的事情:项目,代码,工作,个人生活。它们是否成功都取决于我们是否使用" this"关键字来限定对字段的访问。此关键字不会准时发货。它不会减少错误,不会对代码质量或者可维护性产生任何明显的影响。这样不会加薪,也不会减少我们在办公室的时间。
这实际上只是一个样式问题。如果我们喜欢" this",请使用它。如果我们不这样做,那就不要。如果需要它来获取正确的语义,请使用它。事实是,每个程序员都有自己独特的编程风格。这种风格反映了特定程序员对"最美观的代码"应该是什么样的想法的。根据定义,任何其他读取代码的程序员都将具有不同的编程风格。这意味着我们总会做其他人不喜欢或者做不同的事情。在某个时候,某个家伙会阅读代码并抱怨一些事情。
我不会为此烦恼。我只是要确保代码根据我们自己的喜好在美学上尽可能令人满意。如果我们问10个程序员如何格式化代码,我们将获得大约15种不同的见解。需要重点关注的一点是代码的分解方式。事情是抽象的吗?我是否为事物选择了有意义的名称?有很多代码重复吗?有什么方法可以简化内容吗?我认为正确解决这些问题将对项目,代码,工作和生活产生最大的积极影响。巧合的是,这也可能会使另一个家伙抱怨最少。如果代码能够正常工作,易于阅读且具有充分的理据,那么另一个人将不会仔细检查如何初始化字段。他将使用代码,赞叹它的出色之处,然后再进行其他研究。
回答
在C#中,此关键字有多种用法。
- 资格隐藏以类似名称隐藏的成员
- 使对象将自身作为参数传递给其他方法
- 使对象从方法中返回自身
- 声明索引器
- 声明扩展方法
- 在构造函数之间传递参数
- 要在内部重新分配值类型(结构)值。
- 在当前实例上调用扩展方法
- 转换为其他类型
- 链接在同一类中定义的构造函数
通过在范围内不具有相同名称的成员变量和局部变量,可以避免首次使用,例如,遵循通用的命名约定,并使用属性(Pascal大小写)而不是字段(camel大小写)来避免与局部变量(也就是骆驼)冲突案子)。在C3.0中,可以使用自动实现的属性将字段轻松转换为属性。
回答
这是我使用它的时间:
- 从类内部访问私有方法(以区分)
- 将当前对象传递给另一个方法(如果发生事件,则作为发送者对象)
- 创建扩展方法时:D
我不将其用于私有字段,因为我在私有字段变量名前加了下划线(_)。
回答
就个人而言,在引用成员变量时,我总是尝试使用它。它有助于阐明代码并使其更具可读性。即使没有歧义,第一次阅读我的代码的人也不会知道这一点,但是,如果他们看到这个用法始终如一,他们就会知道他们是否在查看成员变量。
回答
我养成了在Visual C ++中自由使用它的习惯,因为这样做会触发我按'>'键的IntelliSense,并且我很懒。 (并且容易出现错别字)
但是我一直在使用它,因为我可以很方便地看到我正在调用成员函数而不是全局函数。
回答
[C ++]
我同意"必须时使用它"旅的意见。用这种方法不必要地装饰代码不是一个好主意,因为当我们忘记这样做时,编译器不会警告我们。这给希望一直存在的人们带来了潜在的困惑,即他们必须考虑这一点。
那么,我们什么时候使用它?我只是看了一些随机代码并找到了这些示例(我没有通过判断这些是好事还是其他事):
- 将"自己"传递给函数。
- 将"自己"分配给指针或者类似的东西。
- 投射,即向上/向下投射(安全或者其他方式),消除常量性等。
- 编译器强制消除歧义。
回答
除非绝对必要,否则不应使用" this"。
与不必要的冗长相关联的惩罚。我们应该争取的代码应尽可能长,而不再是。
回答
我仅在需要时使用它,除了对称操作(由于单参数多态性必须将其放入一侧的方法中):
boolean sameValue (SomeNum other) { return this.importantValue == other.importantValue; }
回答
[C ++]
这在赋值运算符中使用,在大多数情况下,我们必须检查并防止发生奇怪的(无意识的,危险的,或者只是浪费时间的程序),例如:
A a; a = a;
作业运算符将写为:
A& A::operator=(const A& a) { if (this == &a) return *this; // we know both sides of the = operator are different, do something... return *this; }
回答
C ++编译器上的this
如果C ++编译器没有立即找到符号,它将静默查找符号。有时候,在大多数情况下,这是件好事:
- 如果我们没有在子类中重载它,请使用父类的方法。
- 将一种类型的值提升为另一种类型
但是有时候,我们只是不想让编译器猜测。我们希望编译器选择正确的符号,而不是另一个。
对我来说,那些时候是在方法内,我想访问成员方法或者成员变量的时间。我只是不希望因为我写了printf
而不是print
而捡了一些随机符号。 this-> printf不会被编译。
关键是,对于C遗留库(),几年前编写的遗留代码()或者在复制/粘贴是过时但仍处于活动状态的语言中可能发生的任何事情,有时,告诉编译器不要机智是一种好想法。
这就是我使用" this"的原因。
()对我来说仍然是一个谜,但是我现在想知道我们是否在源代码中包含<windows.h>标头的事实是否是所有旧版C库符号都会污染全局名称空间的原因
()意识到"我们需要包含一个标头,但是包含此标头会破坏代码,因为它使用了具有通用名称的某些哑宏",这是编码者一生中的俄罗斯轮盘赌时刻之一
回答
此关键字的另一种罕见用法是,当我们需要从实现类内部调用显式接口实现时。这是一个人为的例子:
class Example : ICloneable { private void CallClone() { object clone = ((ICloneable)this).Clone(); } object ICloneable.Clone() { throw new NotImplementedException(); } }
回答
在Jakub?turc的回答中,他关于在构造函数之间传递数据的#5可能使用一些解释。这是在重载构造函数中,并且是强制使用this
的一种情况。在以下示例中,我们可以使用默认参数从无参数构造函数中调用参数化构造函数。
class MyClass { private int _x public MyClass() : this(5) {} public MyClass(int v) { _x = v;} }
我发现有时候这是一个特别有用的功能。
回答
我用它像JohnMcG一样调用Intellisense,但完成后我将回去并擦除" this->"。我遵循Microsoft的成员变量前缀为" m_"的约定,因此将其保留为文档将是多余的。
回答
1个常见的Java setter习语:
public void setFoo(int foo) { this.foo = foo; }
2以该对象作为参数调用函数时
notifier.addListener(this);
回答
'这。'帮助找到具有很多成员的"此类"成员(通常是由于深层次的继承链)。
按下CTRL + Space不能解决这个问题,因为它还包括类型。在哪里,如"这个"。仅包括成员。
通常,一旦有了我想要的内容,便将其删除:但这只是我的风格突破。
就风格而言,如果我们是一名独行侠,我们可以自己决定;如果我们在公司工作,请遵守公司政策(查看源代码管理中的内容,看看其他人在做什么)。在使用它来限定成员资格方面,对与错都没有。唯一的错误是不一致-这是样式的黄金法则。离开挑剔的人。花时间思考真正的编码问题,而不是思考编码。
回答
我会尽可能使用它。我相信它使代码更具可读性,可读性更高的代码意味着更少的错误和更高的可维护性。
回答
当我们有许多使用相同代码库的开发人员时,我们需要一些代码准则/规则。在我工作的地方,我们倾向于在字段,属性和事件上使用" this"。
对我来说,这样做很有意义,当我们区分类变量和方法变量时,它使代码更易于阅读。
回答
在C ++中,还没有提到一种用法,即不要引用自己的对象或者使成员与接收的变量消除歧义。
我们可以使用" this"将非依赖名称转换为从其他模板继承的模板类中的参数依赖名称。
template <typename T> struct base { void f() {} }; template <typename T> struct derived : public base<T> { void test() { //f(); // [1] error base<T>::f(); // quite verbose if there is more than one argument, but valid this->f(); // f is now an argument dependent symbol } }
模板使用两次通过机制进行编译。在第一遍过程中,仅解析和检查非参数依赖的名称,而仅检查关联名称的一致性,而无需实际替换模板参数。
在那一步,在没有实际替换类型的情况下,编译器几乎没有任何有关" base <T>"可能是什么的信息(请注意,基本模板的特殊化可以将其转换为完全不同的类型,甚至是未定义的类型),因此它只是假定它是一种类型。在这个阶段,对程序员来说很自然的非依赖调用f'是编译器必须找到它作为
derived`的成员或者包含在命名空间中的符号-在示例中不会发生-并且它将抱怨。
解决方案是将非相关名称" f"转换为相关名称。这可以通过几种方式来完成,方法是明确说明实现的类型(base <T> :: f
-添加base <T>`使得符号依赖于T和编译器将仅假设该参数将存在,并在参数替换后推迟第二遍的实际检查。
第二种方式,如果我们从具有多个参数或者长名称的模板继承的话,那么很多排序方法就是在符号前添加一个" this->"。因为我们要实现的模板类确实依赖于一个参数(它继承自base <T>),所以this->与参数有关,我们得到相同的结果:在第二个中检查this-f一轮,模板参数替换后。
回答
当在一个接受对相同类型对象的引用的函数中,我想使其完全清楚我要指向的对象,位置时,我会使用它。
例如
class AABB { // ... members bool intersects( AABB other ) { return other.left() < this->right() && this->left() < other.right() && // +y increases going down other.top() < this->bottom() && this->top() < other.bottom() ; } } ;
(vs)
class AABB { bool intersects( AABB other ) { return other.left() < right() && left() < other.right() && // +y increases going down other.top() < bottom() && top() < other.bottom() ; } } ;
乍看之下," right()"是指哪个AABB? " this"添加了一些澄清剂。