C#中'this'关键字的用途是什么

时间:2010-01-06 15:12:42

标签: c#

由于在方法内声明的变量仅在该方法中可用,并且在类中声明为private的变量仅在类中可用。 this关键字的目的是什么?为什么我要拥有以下内容:

private static class SomeClass : ISomeClass
{
    private string variablename;
    private void SomeMethod(string toConcat)
    {
        this.variablename = toConcat+toConcat;
        return this.variablename;
    }
}

如果这样做会完全相同:

private static class SomeClass : ISomeClass
{
    private string variablename;
    private void SomeMethod(string toConcat)
    {
        variablename = toConcat+toConcat;
        return variablename;
    }
}

练习我的打字技巧?

19 个答案:

答案 0 :(得分:36)

有几个案例很重要:

  • 如果您有一个函数参数和一个具有相同名称的成员变量,您需要能够区分它们:

    class Foo {
      public Foo(int i) { this.i = i; }
    
      private int i;
    }
    
  • 如果您确实需要引用当前对象,而不是其中一个成员。也许您需要将它传递给另一个函数:

    class Foo {
      public static DoSomething(Bar b) {...}
    }
    
    class Bar {
      public Bar() { Foo.DoSomething(this); }
    }
    

    当然,如果您想返回对当前对象的引用,同样适用

答案 1 :(得分:28)

在你的例子中,这纯粹是一种品味问题,但这是一个不是这样的情况:

private string SomeMethod(string variablename)
{
    this.variablename = variablename;
    return this.variablename;
}

如果没有this,代码将以不同的方式工作,将参数分配给自身。

答案 2 :(得分:15)

在许多情况下这很有用。这是一个例子:

class Logger { 
   static public void OutputLog (object someObj) {
      ...
   }
}

class SomeClass { 
   private void SomeMethod () { 
      Logger.OutputLog (this);
   } 
}

这是另一个例子。假设我正在编写一个输出对象的Stream.Out方法,并返回对流本身的引用,如下所示:

class Stream {
   public Stream Out (object obj) { 
      ... code to output obj ...
      return this; 
   }
}

然后,可以在链接模式下使用此Out呼叫:

Stream S = new Stream (...);
S.Out (A). Out (B). Out (C);

答案 3 :(得分:5)

除了“字段消歧”和“通过当前意义的引用”答案(已经给出)之外,还有一个需要this的情况;在当前实例上调用扩展方法(我忽略了声明扩展方法中this的用法,因为这与问题的含义不完全相同):

class Foo
{
    public void Bar()
    {
        this.ExtnMethod(); // fine
        ExtnMethod(); // compile error
    }
}
static class FooExt
{
    public static void ExtnMethod(this Foo foo) {}
}

公平地说,这不是常见的情况。更可能的是简单地使代码更具可读性,例如:

public bool Equals(Foo other) {
    return other != null && this.X == other.X && this.Y == other.Y;
}

在上面(或类似于CompareClone等),没有this.我发现它有点......“不平衡”。

答案 4 :(得分:4)

如果您的method-parameter与字段名称相同,则需要this

private string variablename;
private void SomeMethod(string variablename)
{
    this.variablename = variablename+variablename;
    return this.variablename;
}

答案 5 :(得分:4)

在大多数情况下,使用this只会使代码混乱。但是,我已经看到它被其他程序员使用,大概是为了触发本地成员的智能感知。

在扩展方法中也需要使用this关键字。

public static class MyExtensions
{
    public static int WordCount(this String str)
    {
        return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
    }
}  

答案 6 :(得分:4)

首先,您的示例存在缺陷,因为您已将该类标记为静态,因此无法实例化。

无论如何,this只是对当前实例的引用。它可用于解决局部变量和成员变量之间的冲突,例如:

public class Foo
{
    private string baz;

    public void Bar(string baz)
    {
        this.baz = baz;
    }
}

它本身也可以简单地用作对象,例如:

public class Foo
{
    public List<Foo> GetList(string baz)
    {
        var list = new List<Foo>();
        list.Add(this);

        return list;
    }
}

(不是说这个例子特别有用,但你明白了。)

编辑:更现实的例子是.NET中的事件模型:

public class Foo
{
    public EventHandler SomeEvent;

    public void Bar()
    {
        if (SomeEvent != null)
        {
            SomeEvent(this, EventArgs.Empty);
        }
    }
}

答案 7 :(得分:3)

除了Javascript之外,“this”主要是一个占位符关键字,最有用的是在编写一段代码时使你的意图变得明显。

基本上它有助于提高可读性。

答案 8 :(得分:3)

首先,当类方法需要将对象的引用传递给另一个类中的某个方法时,这个是必需的。

例如:

class Image
{
    void Refresh()
    {
        Screen.DrawImage(this);
    }
}

与使用或不使用“this”的其他场景不同。是一种风格问题,或解决人为歧义的手段。

答案 9 :(得分:3)

我想到的第一件事是可读性和/或个人偏好。

有时候我正在使用一个相当大的类......或者一个带有基类的类(我无法“看到”某些变量)...我使用“this”关键字......至少对于intellisense在Visual Studio中。

答案 10 :(得分:3)

  1. this表示您当前的班级实例成员不是 一个。你的基类成员
    湾范围成员
    C。静态成员
  2. 使您的代码更具可读性。

答案 11 :(得分:2)

我恭敬地不同意其他一些海报。在C#中,它不仅仅是品味问题;它也符合微软的C#风格指南(内部和外部指导,尽管它们似乎并不符合内部的指导原则)。

有些例子表明您使用的符号不起作用:

private void DoSomething(object input) 
{ 
    input = input; 
} 

相反,您需要使用以下表示法:

private void DoSomething(object input) 
{ 
    this.input = input; 
} 

答案 12 :(得分:2)

this是指该类的实例,在您向我们展示的示例中:您使用this来引用名为variablename的字段。

如果您有一个具有相同名称的局部变量或参数,则需要有一种区分它们的方法。在这种情况下,this将引用该字段,而不是this的前缀引用局部变量或参数。

您应该有一个命名约定,可以帮助您区分字段和本地。这样可以避免以后在方法中添加同名的本地时可能出现的问题。 (因为没有this的代码会破坏...)

答案 13 :(得分:0)

常用用于具有相同名称的构造函数参数:

public SomeClass(string variablename)
{
   this.variablename = variablename;
}

答案 14 :(得分:0)

主要是风格问题。如果您的方法的变量名称与私有类成员相同,则使用此名称有助于消除歧义。这可能会阻止愚蠢的错误。

答案 15 :(得分:0)

1)首先,最重要的是,当一个对象需要传递对自身的引用时:

public class Element{
//...
public Element Parent;
public Element Root()
{
 if( Parent == null )
  return this;
 return Parent.Root();
}
}
public void OnEvent()
{
 Event(this, new EventArgs());
}

在流畅的界面:

public class Query {  public Query Add(参数参数){_ list.Add(parameter);归还这个; } }

2)其次,在和扩展方法:

public class Extension
{
 public Element Root(this Element element) {
  if( element.Parent == null )
   return element;
  return element.Parent.Root();
 }
}

3)第三,你真的不需要它,以区分参数和类成员。 您不需要它,因为良好的编码约定可以避免使用“this”关键字。

public class Element
{
 public Element Parent;
 publlc void SetParent(Element parent)
 {
   // this.Parent = parent; // see, you don't need it
   Parent = parent;
 }
}
//...
public class Element
{
 public Element _parent;
 public Element Parent { get { return _parent; } }
 publlc void SetParent(Element parent)
 {
   // this._parent = parent; // see, you don't need it
   _parent = parent;
 }
}

答案 16 :(得分:0)

有一个原则可以指导您决定是否使用'this'。你需要具体参考这个类的实例吗?如果你这样做,那么使用'this'。否则,请将其留下。

Logger示例提供的另一张海报就是一个很好的例子。他不能依赖于暗示这一点,因为他需要对象本身。

使用'this'作为类本身方法的前缀没有意义,因为它是隐式的。

答案 17 :(得分:0)

我忍不住......

if (this == null)
    throw new NullReferenceException();

[KIDDDIIIING !!!]

答案 18 :(得分:0)

我已经找到了另一种情况:

private int value;
public int Value
{
    get { return this.value; }
    set { this.value = value; } //without this it doesn't make sense
}