何时不应使用“this”关键字?

15

很抱歉再次提问,已经有一些关于这个关键字的问题了。但是它们都只讲述了“this”关键字的用途。

什么时候使用 this 关键字
C# 中什么时候使用 this 关键字
在 C# 中静态方法的形式参数中使用“this”关键字
C# 中“this.”关键字的正确用法?

我的问题是在什么情况下不使用 'this' 关键字
或者
在像代码这样的情况下始终使用此关键字是否合适

class RssReader
{
    private XmlTextReader _rssReader;
    private XmlDocument _rssDoc;
    private XmlNodeList _xn;

    protected XmlNodeList Item { get { return _xn; } }
    public int Count { get { return _count; } }

    public bool FetchFeed(String url)
    {
        this._rssReader = new XmlTextReader(url);
        this._rssDoc = new XmlDocument();
        _rssDoc.Load(_rssReader);
        _xn = _rssDoc.SelectNodes("/rss/channel/item");
        _count = _xn.Count;
        return true;
    }
}

在这段代码中,我在"_xn"和"_count"以及"_rssDoc.Load(_rssReader);"中没有使用'this'关键字,这样做是否合适?我应该在类内部的所有类变量出现时都使用"this"吗?

编辑:在一个类中为自己的变量使用'this'是否是无用的


2
尽管有__NOT__,但这是一个可能的重复副本的副本C#何时使用“This”关键字 - H H
1
可能是When do you use the "this" keyword?的重复问题。 - ChrisF
我在一开始就说过:“很抱歉再次提问,已经有3个问题涉及到这个关键词了。” - SMUsamaShah
这是关于同一件事情,但问题不同。 - SMUsamaShah
如果你真的认为这不是一个重复的问题,那么你至少应该链接到其他三个问题。 - Christian Payne
12个回答

25

总是使用 this。我对局部变量和私有字段使用相同的命名约定,这使得代码更容易阅读,因为使用的标识符是字段还是局部变量显而易见。

此外,它可以防止通过添加一个新的局部变量来隐藏字段引入错误。

internal sealed class Foo
{
    private Int32 bar = 42;

    private void Bar()
    {
        // Uncommenting the following line will change the
        // semantics of the method and probably introduce
        // a bug.  
        //var bar = 123;

        Console.WriteLine(bar);

        // This statement will not be affected.
        Console.WriteLine(this.bar);
    }
}

可以通过为字段和局部变量使用不同的命名约定来避免这种情况,但我真的不喜欢下划线前缀的名称。单词的第一个字符对其可读性非常重要,而下划线是最糟糕的选择之一。


2
个人而言,我喜欢使用下划线,因为它很繁琐且看起来不美观。它提醒我尽可能对字段进行封装,并通过属性访问器进行访问,即使在类内部也是如此。而且,“this.”只是我不必键入的五个字符。 - TrueWill
@BrianOrtiz 因为使用一种如此注重防呆的语言,我不明白为什么人们不想写五个字符。说实话,我很喜欢 Python 和 Js 强制引用实例。 - Alvaro

18

this通常是可选的,不需要特别指定。如果你想明确表示你正在引用一个成员,那么使用this。如果你有一个命名约定(例如将所有成员字段命名为_foo之类的名称),那么你真的不需要像this._foo这样引用它们。

这是个人口味问题(没有性能损失),但我发现明确使用this更难维护,并且如果你有一个良好的命名约定,添加的价值很小。一些人仅在调用成员方法时使用this,例如 this.Foo(_bar)而非Foo(_bar),但同样地,我个人认为它并没有增加太多价值。

如果你正在处理现有的代码,请遵循那里的约定,否则,选择让你最具生产力和效率的方式。


我明白了!就像其他人说的那样,这真的很冗余。 - SMUsamaShah
3
补充一下,使用“this”的另一个好处是,当你传入一个与你正在设置的私有字段同名的参数时,可以避免命名冲突。 - James
1
@詹姆斯...使用这个的另一个原因是...在创建扩展方法时。 - taher chhabrawala

14

我的经验法则是:当'this'多余时,永远不要使用它。在这种情况下,'this'是多余的,所以我会避免使用它。类似于ReSharper的工具非常善于告诉你何时出现了这种情况。


我已经下载了它,但还没有尝试过。是的,冗余看起来很奇怪。我可以假设在类中使用它的变量是无用的,因为它没有任何效果吗? - SMUsamaShah
是的,这是正确的假设。如果成员变量与作用域内的变量同名,您必须使用“this”来消除歧义。您还需要在构造函数链接、扩展方法和其他一些微妙的情况下使用它。 - Brian Genisio
我只在编写代码时使用它,将一个1000行长的块包装在一个区域中。 - Ritch Melton

9
我总是使用this.来明确我正在引用类成员变量,而不是局部变量。

3

我在类内部的所有类变量中都应该使用"this"吗?

在您特定的情况下,不需要。

但请考虑以下示例:

class RssReader
{
    private String url;

    public bool FetchFeed (String url)
    {
        new XmlTextReader (url);

        // vs.

        new XmlTextReader (this.url);

        return true;
    }
}

在这里,您需要指定this来访问与方法参数名称相同的实例变量。


3

我会尽力保持一致,这样人们就不会因为你偶尔采用不同的方式(除了你通常使用的方式)而产生误解以为有特殊意义。

如果您不使用_字段命名约定,则应始终使用this.whatever,否则在构造函数接受whatever参数并尝试放入whatever字段时会出现问题。


3

很好。尤其是因为你的类没有基类,私有字段的命名也很合适。ReSharper认为在你的情况下this是多余的。


3

绝对没有理由不使用它。即使是冗余,也绝不是不使用的理由。您可以获得智能感知框以安全地完成代码,并通过向下键选择正确的变量来节省时间,而不必一直按键盘。


2

除非你的方法需要区分与类变量同名的参数,否则可以选择不这样做。


1
这是我的看法。当您在实例范围内以以下方式调用类的成员(无论是方法、属性还是字段)DoMyThing();return Property;时,您并不一定是在调用实例成员。 DoMyThingProperty 也可以是静态成员。
public class Abc
{
    public static void Static()
    {
    }

    public Xyz Instance;

    public void Test() //instance scope
    {
        var xyz = Instance; //calls instance member
        Static(); //calls static member
    }
}

对于这两个(静态和实例)我没有添加任何前缀。实际上,我的选择是:
  1. 完全不需要前缀,如上所述

    public void Test()
    {
        var xyz = Instance;
        Static();
    }
    
  2. 仅为实例成员添加前缀

    public void Test()
    {
        var xyz = this.Instance; // 添加'this'前缀
        Static(); 
    }
    
  3. 仅为静态成员添加前缀

    public void Test()
    {
        var xyz = Instance; 
        Abc.Static(); // 添加类名前缀
    }
    
  4. 两种情况都添加前缀

    public void Test()
    {
        var xyz = this.Instance; // 添加'this'前缀
        Abc.Static(); // 添加类名前缀
    }
    
这个回答并不是说一种风格比另一种更好。这只是个人喜好而已。每种风格都有其正确性和可读性的主张。
我认为:
a. 我个人不喜欢2和3的不一致风格。
b. 1更容易被我理解。前缀使其更多关于定义而非意图。
c. 4全都是关于正确性。它的优点在于极度一致,特别是考虑到你迟早会强制为实例静态成员添加前缀。当涉及到基类成员时更加重要,如果你没有使用base关键字为基类成员添加前缀,那么在当前派生类中添加一个同名成员将会导致覆盖先前的调用,改变整个动态。

个人而言,我会选择1。并在必要时仅适度使用thisAbc。这对我来说更易读,这是一个足以弥补它可能造成的轻微不一致性的好处。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接