使用静态方法和变量 - 好与坏

时间:2011-09-08 10:21:20

标签: c# static static-methods static-members

我正在开发C#和asp.net Web应用程序。

我有一个名为utilities的通用类,我在这个公共实用程序类中有很多公共和静态变量。

由于这个数字逐渐增加,我想知道将实用程序方法和变量存储为公共静态是一种好习惯。

我的代码示例

public class utilities
{
    public static string utilVariable1 = "Myvalue";
    public static string utilVariable2 = "Myvalue";
    public static string utilVariable3 = "Myvalue";
    :
    public static string utilVariableN = "Myvalue";


    public static string UtilMethod1()
    {
         //do something
    }

    public static string UtilMethod2()
    {
         //do something
    }

    public static string UtilMethodN()
    {
         //do something
    }
}

5 个答案:

答案 0 :(得分:12)

static类没有任何内在错误,尽管它们通常不应该有状态(字段)。您对public static字段的使用表明情况并非如此,因此您似乎正在使用稍微滥用static关键字。如果你的类需要有状态,那么它应该是一个普通的非静态类,你应该创建它的实例。否则,该类中唯一可见的公共字段应为const(考虑Math类,使用Math.PI等常量 - 充分利用static方法和字段)

另一个考虑是凝聚力。方法通常存在于一个类中,因为它们以某种方式密切相关。同样,Math类是一个很好的例子;那里的一切都与数学有关。在某些时候,您可能希望将全局实用程序类拆分为多个更小,更集中的实用程序类。有关凝聚力的一些例子,请参阅Wikipedia,听起来你的用法属于“巧合的凝聚力(最差)”。

答案 1 :(得分:6)

这种方法对于方法没有任何问题,但如果它们变得静态和公开,变量应该是常量。如果它们可能会发生变化,那么您应该查看由多个组件操纵的变量的不同结构。

就个人而言,我是Singleton模式的粉丝。

答案 2 :(得分:2)

static本身并不是一件坏事。不需要访问任何成员变量或方法的方法应始终声明为static。这样,代码的读者立即看到方法不会改变成员变量或方法。

对于变量情况不同,除非您将static变为const,否则应避免使用Public static变量。 {{1}}变量是全局可访问的,如果多个线程在没有正确同步的情况下访问同一个变量,则很容易引发问题。

很难说你的情况是否使用静态是好的还是坏的,因为你没有提供任何上下文信息。

答案 3 :(得分:2)

创建一个类来完成这一切并不是一个好习惯,建议构建项目,并保持彼此相关的东西与随机性分开。

这方面的一个很好的例子是我从同事手中接过的一个项目。有一个类叫做Methods。它包含超过10K行的方法 然后我将它们分类为约。 20个文件,结构已恢复。

该项目的大部分方法都是验证用户输入,可以很容易地将其移动到static class Validation

我注意到的一件可怕的事情是可变的公共和静态变量。这有几个原因:

  1. 行为不正确,因为如果某些方法改变了这一点,虽然它不应该这样做,但它会导致其他方法行为不正确,而且很难追踪/调试。
  2. 并发,我们如何确保线程安全?我们是否让它适用于所有与之相关的方法?如果它是一个值类型,我们会让它们锁定什么?如果某种方法忘记使其线程安全怎么办?
  3. 扩展能力(我希望你明白我的意思),如果你有一个静态类数据存储所有这些公共静态变量,你不应该有。它可以存储一次,例如,如果你可能稍微改变你的应用程序结构,并说想要在同一个屏幕上加载两个项目,那么很难做到这一点,因为你不能创建两个静态类的实例。只有一个班级,它会保持这样的状态。
  4. 对于3号,更清洁的解决方案是存储数据类实例列表,或者存储对默认和/或活动数据类的引用。

    静态成员和私有静态成员(或受保护的)是一种很好的做法,只要你不创建庞大的类,并且方法是相关的。

    如果公共变量和静态变量不是真正可变的话,那么这些变量是可以的 这两种方法是将它们标记为常量(const修饰符)或只读(readonly修饰符)。

    示例:

    public class UtilitiesClass
    {
        internal UtilitiesClass() { }
    
        public void UtilityMethod1()
        {
            // Do something
        }
    }
    
    // Method 1 (readonly):
    public static readonly UtilitiesClass Utilities = new UtilitiesClass();
    
    // Method 2 (property):
    private static UtilitiesClass _utilities = new UtilitiesClass();
    public static UtilitiesClass Utilities
    {
        get { return _utilities; }
        private set { _utilities = value; }
    }
    

    方法1的优点是您根本不必担心线程安全,价值无法改变。
    方法2不是线程安全的(尽管它并不困难),但它的优点是允许静态类本身更改对实用程序类的引用。

答案 4 :(得分:1)

不,对于大型应用程序来说,这不是一个好习惯,特别是如果你的静态变量是可变的,因为它们实际上是全局变量,这是面向对象编程应该“解决”的代码味道。

至少首先将您的方法分组为具有相关功能的较小类 - Util名称不表示您的方法的目的和本身不连贯类的气味。

其次,您应该始终考虑一个方法是否更好地实现为同一对象上的(非静态)方法,其中作为参数传递给该方法的数据存在。

最后,如果您的应用程序非常庞大和/或复杂,您可以考虑诸如Inversion of Control容器之类的解决方案,这可以减少对全局状态的依赖。但是,ASP.Net webforms非常难以集成到这样的环境中,因为框架本身非常紧密地耦合。