What is the purpose of 'this' keyword in C#
因为方法中声明的变量仅在该方法中可用,而类中声明为私有的变量仅在类中可用。
1 2 3 4 5 6 7 8 9 | private static class SomeClass : ISomeClass { private string variablename; private void SomeMethod(string toConcat) { this.variablename = toConcat+toConcat; return this.variablename; } } |
当这将做完全相同的事情时:
1 2 3 4 5 6 7 8 9 | private static class SomeClass : ISomeClass { private string variablename; private void SomeMethod(string toConcat) { variablename = toConcat+toConcat; return variablename; } } |
练习打字技巧?
有几个情况很重要:
如果函数参数和成员变量具有相同的名称,则需要能够区分它们:
1
2
3
4
5class Foo {
public Foo(int i) { this.i = i; }
private int i;
}如果实际需要引用当前对象,而不是其成员之一。也许您需要将它传递给另一个函数:
1
2
3
4
5
6
7class Foo {
public static DoSomething(Bar b) {...}
}
class Bar {
public Bar() { Foo.DoSomething(this); }
}当然,如果您想返回对当前对象的引用,同样适用
在您的示例中,这纯粹是一个品味问题,但这里的情况并非如此:
1 2 3 4 5 | private string SomeMethod(string variablename) { this.variablename = variablename; return this.variablename; } |
如果没有
在许多情况下,这是有用的。下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 | class Logger { static public void OutputLog (object someObj) { ... } } class SomeClass { private void SomeMethod () { Logger.OutputLog (this); } } |
这是另一个例子。假设我正在编写一个stream.out方法,该方法输出一个对象,并返回对流本身的引用,如下所示:
1 2 3 4 5 6 | class Stream { public Stream Out (object obj) { ... code to output obj ... return this; } } |
然后,可以在链接模式下使用这个out调用:
1 2 |
除了"字段消歧"和"传递当前istance的引用"答案(已经给出)之外,还有一个附加的场景,其中
1 2 3 4 5 6 7 8 9 10 11 12 | class Foo { public void Bar() { this.ExtnMethod(); // fine ExtnMethod(); // compile error } } static class FooExt { public static void ExtnMethod(this Foo foo) {} } |
公平地说,这不是常见的情况。更可能的方法是简单地提高代码的可读性,例如:
1 2 3 | public bool Equals(Foo other) { return other != null && this.X == other.X && this.Y == other.Y; } |
在上面(或类似于
如果方法参数与字段同名,则需要
1 2 3 4 5 6 | private string variablename; private void SomeMethod(string variablename) { this.variablename = variablename+variablename; return this.variablename; } |
在大多数情况下,使用
扩展方法中也需要使用
1 2 3 4 5 6 7 | public static class MyExtensions { public static int WordCount(this String str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } } |
首先,您的示例是有缺陷的,因为您已经将类标记为静态的,所以它不能被实例化。
无论如何,
1 2 3 4 5 6 7 8 9 | public class Foo { private string baz; public void Bar(string baz) { this.baz = baz; } } |
它也可以简单地作为一个对象来使用,例如:
1 2 3 4 5 6 7 8 9 10 | public class Foo { public List<Foo> GetList(string baz) { var list = new List<Foo>(); list.Add(this); return list; } } |
(不是说这个例子特别有用,但你明白了。)
编辑:更现实的例子是.NET中的事件模型:
1 2 3 4 5 6 7 8 9 10 11 12 | public class Foo { public EventHandler SomeEvent; public void Bar() { if (SomeEvent != null) { SomeEvent(this, EventArgs.Empty); } } } |
首先,当一个类方法需要将对对象的引用传递给另一个类中的某个方法时,这是必需的。
例如:
1 2 3 4 5 6 7 | class Image { void Refresh() { Screen.DrawImage(this); } } |
与其他一些使用或不使用"this"的场景不同,它是一种风格问题,或解决人为模糊性的方法。
我首先想到的是可读性和/或个人偏好。
有时当我在一个相当大的班级工作时…或者一个带有基类的类(在这里我看不到一些变量)。我用这个关键词…至少对于Visual Studio中的IntelliSense。
a.您的基类成员
b.范围成员
c.静态构件
除了可能的javascript之外,"this"主要是一个占位符关键字,最有用的是在编写一段代码时使您的意图变得明显。
基本上,它将有助于可读性。
我尊重地不同意其他一些海报。在C中,这不仅仅是一个品味问题,它还符合微软的C风格指导原则(内部和外部,尽管他们似乎不符合自己的指导原则)。
例如,当您使用的符号不起作用时:
1 2 3 4 | private void DoSomething(object input) { input = input; } |
相反,您需要使用以下符号:
1 2 3 4 | private void DoSomething(object input) { this.input = input; } |
如果您有一个同名的局部变量或参数,那么您需要有一种区分它们的方法。在这种情况下,
您应该有一个命名约定来帮助您区分字段和本地变量。如果您以后向方法中添加具有相同名称的本地变量,这将使您免受可能发生的问题的影响。(因为没有
我已经找到另一个场景:
1 2 3 4 5 6 | private int value; public int Value { get { return this.value; } set { this.value = value; } //without this it doesn't make sense } |
1)首先,也是最重要的,是当一个对象需要传递一个对其自身的引用时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Element{ //... public Element Parent; public Element Root() { if( Parent == null ) return this; return Parent.Root(); } } public void OnEvent() { Event(this, new EventArgs()); } |
在Fluent界面中:
公共类查询{公共查询添加(参数参数)列表.添加(参数);返回此;}
2)二次进展法:
1 2 3 4 5 6 7 8 | public class Extension { public Element Root(this Element element) { if( element.Parent == null ) return element; return element.Parent.Root(); } } |
3)第三,你真的不需要它来区分参数和类成员。您不需要它,因为良好的编码约定可以避免使用"this"关键字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; } } |
有一个原则可以指导您决定是否使用"this"。您需要具体地引用这个类的实例吗?如果你这样做了,那就用"这个"。否则,把它放在一边。
记录器示例提供的另一个海报就是一个很好的例子。因为他需要物体本身,所以他不能依赖于一个隐含的事实。
在类本身中,使用"this"作为类本身的方法的前缀是没有意义的,因为它是隐式的。
常用于具有相同名称的构造函数参数:
1 2 3 4 | public SomeClass(string variablename) { this.variablename = variablename; } |
它主要是一个风格问题。如果您的方法有一个与私有类成员相同的变量名,那么使用它有助于消除歧义。这可能会防止愚蠢的错误。
我忍不住…
1 2 |
[孩子们!!!!]