C#最佳实践的误解?

5

我的同事一直在告诉我评论中列出的这些事情。

我很困惑。 有人能否为我解开这些事情的神秘面纱?

class Bar
{
    private int _a;

    public int A
    {
        get { return _a; }
        set { _a = value; }
    }

    private Foo _objfoo;

    public Foo OFoo
    {
        get { return _objfoo; }
        set { _objfoo = value; }
    }

    public Bar(int a, Foo foo)
    {
        // this is a bad idea
        A = a;
        OFoo = foo;
    }

    // MYTHS
    private void Method()
    {
        this.A    //1 -
        this._a   //2 - use this when inside the class e.g. if(this._a == 2)
        A         //3 - use this outside the class e.g. barObj.A
        _a        //4 - 
                  // Not using this.xxx creates threading issues.
    }
}
class Foo
{
    // implementation
}
5个回答

10

如果没有名称冲突,则this.是多余的。只有当需要引用当前对象或者存在与字段同名的参数时才需要使用它。

线程问题与此无关。混淆可能来自于大多数静态成员被实现为线程安全,而静态成员不能使用this.调用,因为它们不绑定到实例。


谢谢Lucero!这肯定会在我们下一次的<strike>会议</strike>对抗中有所帮助 ;) - Pratik Deoghare
1
我认为这应该用于善良的目的,而不是用于对抗。 - Kashif
@Muhammad Kashif Nadeem:知识是一把双刃剑,它的使用取决于持有它的人!开个玩笑:D - Pratik Deoghare
2
静态字段和属性本质上并不是线程安全的。只要它们不使用在静态字段/属性中存储的状态,方法通常是线程安全的。如果正确使用监视器和锁定,属性和方法可以更加线程安全。 - Matthew Whited
@Matthew Whited,或使用正确结构的无锁算法(比使用监视器或锁要快得多,尽管仅在时间关键场景中需要)。 - Grant Peters

8
“不使用this.xxx会产生线程问题”是一个完全错误的说法。请让你的同事检查生成的IL,并让他解释为什么无论你是否添加“this”,它们都是相同的。
在类内部使用“this”(例如,如果(this._a == 2))取决于你想要实现什么目标。你的同事似乎在说始终引用私有字段,这对我来说似乎不明智。通常情况下,即使在类内部,您也希望访问公共属性,因为getter可能会修改值(例如,当列表为空时,类型为List的属性可能返回一个新的List实例以避免访问该属性时发生空引用异常)。

1
始终引用私有字段。我认为你的意思是私有字段,而不是属性。 - Lucero
你说得很对,Lucero - 我已经编辑了我的回答以反映这一点。谢谢。 - Dan Diplo
3
此外,OP,请想象使用像public int A { get { return _a; } set { if(value < 0) throw new ArgumentOutOfRangeException(); _a = value; } }这样的属性来执行this._a = -2; - ANeves

4

我的个人“最佳实践”是始终使用这种方式。是的,它有些冗余,但是当你考虑多线程应用程序时,从第一眼就可以很好地识别实例状态何时被更改或检索。


“this.” 是我在代码中最喜欢看到的一种“噪音”。大多数情况下,我会尽量删除尽可能多的噪音(额外的括号、嵌套的if块等)。 - Matthew Whited
这也是StyleCop推荐的。 - Stefan Egli
但是要使用 this._a 还是 this.A - Pratik Deoghare
我喜欢 StyleCop 给我的限制。StyleCop 强制我们在实例字段上始终使用 this.。我喜欢这种“噪音”。 - Steven
有趣的是,ReSharper建议相反的操作(删除this.)。 - Jacob Stanley

3
可能有助于问问您的同事为什么认为这些建议是最佳实践?通常人们会引用他们在某处听说的最佳实践“规则”,却没有真正理解实践背后的原因。
正如Lucero所说,如果没有名称冲突,则不需要“this”。然而,一些人喜欢在不严格要求时包含“this”,因为他们认为这可以提高可读性/更清楚地显示程序员的意图。在我看来,这是个人偏好而不是别的什么问题。
至于您的“Bar”方法中的“bad idea”:您的同事可能认为这是不好的做法,原因是如果“A”的setter方法被修改以产生某种副作用,那么A=a;也将产生这种副作用,而_a = a;只会设置私有变量。在我看来,最佳实践是意识到差异而不是偏好一个而不是另一个。
最后,“线程问题”是无稽之谈——据我所知,“this”与线程无关。

2

数字 2 是一个迷思,只要提到自动属性就可以轻松揭穿它。自动属性允许您定义一个属性而不需要后备字段,这个字段会被编译器自动生成。因此,问问你的同事对于自动属性持有什么看法。


1
除此之外,使用#2会失去getter中可能存在的任何业务逻辑(现在或将来)。有时我使用我的getter来应用默认值。例如,如果后备字段为空,则创建一个新实例,存储到后备字段,然后返回新值。 - Matthew Whited

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