是通过他们的公共访问者糟糕的形式访问本地私有变量?

时间:2009-03-10 13:48:47

标签: c#

我正在开发一个多线程的应用程序。我正在处理报告并跟踪当前批次中的报告数量以及处理的报告总数。每当我更新计数器时,我还需要更新GUI上的标签,因为该过程在一个单独的线程上,需要调用委托。哪一个是更好的方法?

private void UpdateTotalCount(int newValue)
{
    totalCount = newValue;
    if (labelTotalCount.InvokeRequired)
        BeginInvoke((MethodInvoker) delegate() { 
            labelTotalCount.Text = "Total reports:" + totalcount; });
    else
        labelTotalCount.Text = "Total reports:" + totalcount;
}

private int totalCount;
public int TotalCount
{
    get { return totalCount; }
    set {
        totalCount = value;
        if (labelTotalCount.InvokeRequired)
            BeginInvoke((MethodInvoker) delegate() { 
                labelTotalCount.Text = "Total reports:" + totalcount; });
        else
            labelTotalCount.Text = "Total reports:" + totalcount;
    }
}

编辑:好的,第三个选项。


private void UpdateTotalCountLabel()
{
    if (labelTotalCount.InvokeRequired)
        BeginInvoke((MethodInvoker) delegate() { 
            labelTotalCount.Text = "Total reports:" + totalcount; });
    else
        labelTotalCount.Text = "Total reports:" + totalcount;
}
// code elsewhere would look like this
totalCount++;
UpdateTotalCountLabel();
//or
totalCount+= curBatch.Length;
UpdateTotalCountLabel();

7 个答案:

答案 0 :(得分:3)

我认为使用公共访问器更好,因为它允许更多可管理的代码以防您以后需要更改计算总值的方式。这样,TotalValue属性的用户无需担心您的更改,因为这些更改不会以任何方式影响他们的代码。

答案 1 :(得分:3)

我使用观察者设计模式并将更新逻辑移动到观察者类 不要混淆逻辑和GUI。

答案 2 :(得分:1)

(更新:我误读了选项的顺序并让它们反转 - EM)

由于您的代码是“做某事”(在外部组件上设置计数标签),通常认为第一种形式更好。

但是 - OOP纯粹主义者会对此强烈反对 - 这两个版本都不是非常错误的。我已经完成并看到了两者。我不会为了它而重写看起来像#2的代码。

在某些情况下,第二种选择实际上可能比第一种更明智。例如,如果代码需要出于其他原因跟踪计数器并设置并获得很多,那么将标签写为View副作用以及count属性的设置/获取可能是有意义的。作为主要神器。在那种情况下,我会选择属性获取/设置对。

更新: 关于新的第三种选择:

我实际上不推荐这个想法。现在你已经分成两个独立的代码,两个总是必须一起发生的动作;这是净亏损。您可能会忘记在代码中的某处执行其中一个操作。 #1或#2都优于#3。

答案 3 :(得分:1)

我一直认为属性等同于获取/设置访问器方法。获取/设置访问器的经验法则是它们通常应该用于公共接口。如果一个类调用它自己的访问器方法,它们可能应该在另一个类中。

我认为这是代码味道。

答案 4 :(得分:1)

我更喜欢第一个或

private void UpdateTotalCount(int newValue)
{
    totalCount = newValue;
    if (labelTotalCount.InvokeRequired)
        BeginInvoke((MethodInvoker) delegate() { 
            labelTotalCount.Text = "Total reports:" + totalcount; });
    else
        labelTotalCount.Text = "Total reports:" + totalcount;
}

第二个我不喜欢,因为它破坏了封装。我还会修改方法名称以使其更具描述性,例如'UpdateTotalLabelCountAsync',因为这是方法正在执行的操作。

由于您现在正在处理代码,因此您可以将其放入属性设置器中。但是,当其他人甚至您以后去做维护工作时,您可能看不到标签的设置方式。至少使用该方法,您可以确切地知道标签的设置方式。此外,属性还用于存储未更新UI的数据。您也可以将该属性移出UI层并存储另一个位置。

答案 5 :(得分:1)

我喜欢选项4:

private int totalCount;
public int TotalCount
{
    get { return totalCount; }
    set {
            totalCount = value;
            UpdateTotalCountLabel(totalCount);
        }
}

明确界定意图和范围,易于遵循的逻辑 - 什么是不爱?

答案 6 :(得分:0)

我实际上赞成#1,因为它清楚地传达了你某事,而不是设置一个字段。

但是,我同意Mykola的观点,即您的UI互动不应属于与您的支持逻辑所属的同一个类。

相关问题