我正在阅读Head First C#这本书(到目前为止一直很顺利),但是我在使用“this”的语法方面遇到了很多麻烦。关键字。
从概念上讲,我认为我应该使用它来避免参数掩码具有相同名称的字段,但是我通过他们的示例实际跟踪它时遇到了麻烦(同样,它们似乎没有一个专门针对该特定关键字的部分,他们只是解释它并开始在他们的示例中使用它)。
在应用“this”时,有没有人有任何好的经验法则?或者任何在线教程以与Head First C#不同的方式解释它?
谢谢!
答案 0 :(得分:11)
就个人而言,我个人只会使用它:
构造函数链接:
public Foo(int x) : this(x, null)
{
}
public Foo(int x, string name)
{
...
}
从参数名称复制到字段中(在Java中不像C#中那样常见,因为您通常使用属性 - 但在构造函数中很常见)
public void SetName(string name)
{
// Just "name = name" would be no-op; within this method,
// "name" refers to the parameter, not the field
this.name = name;
}
参考此对象,不涉及任何成员:
Console.WriteLine(this);
声明扩展方法:
public static TimeSpan Days(this int days)
{
return TimeSpan.FromDays(days);
}
其他一些人总是使用它(例如用于其他方法调用) - 我个人觉得这样做会让事情变得混乱。
答案 1 :(得分:2)
StyleCop的默认编码样式强制执行以下规则:
A1101:对{方法或属性的调用 name}必须以'this'开头。 前缀表示该项目是 班上的成员。
这意味着属于当前类的每个方法,字段,属性都将以此为前缀。我最初对这条规则有抵触,这使得你的代码更加冗长,但是从那以后它就越来越大,因为它使代码非常清晰。 This thread discusses the question。
答案 2 :(得分:1)
我写this.
当且仅当它增强了可读性时,例如,在实现Comparable
接口时(Java,但想法是相同的):
public void compareTo(MyClass other) {
if (this.someField > other.someField) return 1;
if (this.someField < other.someField) return -1;
return 0;
}
关于参数阴影(例如在构造函数中):我通常给那些相应字段的较短名称,例如:
class Rect {
private int width, height;
public Rect(int w, int h) {
width = w;
height = h;
}
}
答案 3 :(得分:0)
基本上,this
为您提供了对当前对象的引用。您可以使用它来访问对象上的成员,或将当前对象作为参数传递给其他方法。
几乎在所有情况下,在访问成员变量或方法调用之前放置它是完全没有必要的,尽管某些样式指南会出于各种原因推荐它。
就个人而言,我确保将我的成员变量命名为与我的参数明显不同,以避免使用'this'。例如:
private String _someData;
public String SomeData
{
get{return _someData;}
set{_someData = value;}
}
这是一个个人偏好,有些人会建议您将属性和成员变量命名为相同(只是大小写差异 - 'someData'和'SomeData')并在访问私有成员时使用this关键字表明差异。
至于经验法则 - 避免使用它。如果您发现自己使用它来区分本地/参数变量和成员变量,那么重命名其中一个,这样您就不必使用'this'。
我将使用它的情况是多个构造函数,传递对其他方法和扩展方法的引用。 (有关示例,请参阅Jon's answer)
答案 4 :(得分:0)
如果在类中使用相同类的字段的方法,则可以使用此方法。
public class FullName
{
public string fn { set; get; }
public string sn { set; get; }
//overriding Equals method
public override bool Equals(object obj)
{
if (!(obj is FullName))
return false;
if (obj == null)
return false;
return this.fn == ((FullName)obj).fn &&
this.sn == ((FullName)obj).sn;
}
//overriding GetHashCode
public override int GetHashCode()
{
return this.fn.GetHashCode() ^ this.sn.GetHashCode();
}
}