【问题标题】:When should I write Static Methods?我什么时候应该写静态方法?
【发布时间】:2010-09-17 04:24:24
【问题描述】:

所以我了解什么是静态方法或字段,我只是想知道何时使用它们。也就是说,在编写代码时,哪些设计适合使用静态方法和字段。

一种常见的模式是将静态方法用作静态工厂,但这也可以通过重载构造函数来轻松实现。正确的?例如:

var bmp = System.Drawing.Bitmap.LoadFromFile("Image01.jpg");

对于静态字段,创建单例对象是他们的最佳用途吗?

【问题讨论】:

    标签: c# oop


    【解决方案1】:

    静态方法通常适用于不需要来自类实例(来自this)的任何数据并且可以仅使用它们的参数来执行其预期目的的操作。
    一个简单的例子是一个方法Point::distance(Point a, Point b);,它计算两点之间的距离并且不需要实例。

    静态字段对于不经常更改并且被类的所有实例使用的常量非常有用。

    【讨论】:

    • 所以只有当我们想访问'this'类的数据成员时才应该创建非静态方法?
    【解决方案2】:

    当您使用静态工厂时,它可以更好地了解意图 - 它还允许您拥有不同的工厂,它们采用相同的参数类型但具有不同的含义。例如,想象一下如果 Bitmap 有 LoadFromResource(string) —— 不可能有两个都接受 string 的构造函数。

    编辑:来自 cmets 中的 stevemegson

    静态工厂也可以返回 null,并且可以更轻松地返回它从缓存中获取的实例。我的许多类都有一个静态 FromId(int) 来从主键中获取一个实例,如果我们有一个缓存实例,则返回一个现有的缓存实例。

    【讨论】:

      【解决方案3】:

      只要你有独立于实例状态的函数,我会说使用静态方法,即。不依赖于任何实例字段。

      方法所依赖的非本地状态越少,就越容易理解,因此static 对代码读者来说是一个有用的信号。

      【讨论】:

      • 如果我理解正确,您是说 alawys 尽可能使用静态方法。但这感觉不对。在 .NET 基类库中有很多情况下方法可以是静态的,但不是。
      • @wedge - 同意,我今天正在调试一些 .NET 源代码,这让我有些不寒而栗,也让我对我编写的一些狡猾的代码感觉更好:)
      【解决方案4】:

      我通过记住实例方法在单个对象上/内部工作,而静态方法为类做一些事情来保持清楚。

      在 LoadFromFile() 的情况下,您需要一个静态方法,因为如果加载失败,您需要一个空引用 - 实例还不存在。如果您将其实现为构造函数,则必须在失败时抛出异常。

      静态的其他良好用途:Compare(obj a, obj b)、Delete(obj a) 用于数据对象(对象不能删除自身,因为它的引用仍然存在),或用于诚实的过程代码的静态类无法在对象中建模。

      【讨论】:

        【解决方案5】:

        当方法不属于特定对象时使用静态方法。

        例如,如果您查看 .NET 框架中的 Math 类,您会看到 所有方法都是静态的。为什么?因为没有理由必须创造 使用方法的对象。为什么要创建一个对象 Math 类,什么时候你想要的只是某物的绝对值?不在这里 没有理由这样做,因此该方法是静态的。

        所以当你设计一门课时,问问自己:

        这个方法是属于一个对象,还是属于类本身?

        一个方法属于一个对象,如果它修改了对象的状态。如果 该方法不会修改特定对象,它很可能是静态的。

        另一个例子,假设你想知道一个类有多少个对象 这是创建的(不要问我为什么......)。对于此任务,您可以创建一个 静态方法GetNumberOfObjects()(你显然需要一个静态字段, 以及构造函数中的一些代码)。为什么我要让它是静态的,你可能会 问。那么,回答上面的问题,你会看到。该方法不 属于任何特定对象。此外,它不会修改任何对象。

        我希望这是有道理的。

        【讨论】:

        • 很好的例子和回复
        【解决方案6】:

        只要您有一个不依赖于该类的特定对象的函数,您就应该使用静态方法。

        添加 static 关键字并没有什么坏处:它不会破坏任何引用它的代码。因此,例如,无论您是否具有“静态”关键字,以下代码都是有效的:

        class Foo
        {
            public Foo(){}
            public static void bar(){}  // valid with or without 'static'
            public void nonStatic(){ bar(); }
        }
        
        ...
        Foo a = new Foo();
        a.bar();
        

        因此,您应该将“静态”添加到您可以使用的任何方法中。

        【讨论】:

          【解决方案7】:

          以下是您可能希望使用静态方法的一些示例:

          1) 当函数不使用任何成员变量时。您不必在这里使用静态方法,但如果这样做通常会有所帮助。

          2) 使用工厂方法创建对象时。如果您事先不知道要创建的类型,则它们尤其必要:例如

          class AbstractClass {
              static createObject(int i) {
                  if (i==1) {
                     return new ConcreteClass1();
                  } else if (i==2) {
                     return new ConcreteClass2();
                  }
               }
          }
          

          3) 当您控制或以其他方式跟踪类的实例化数量时。 Singleton 是最常用的例子。

          4) 声明常量时。

          5) 对类的多个对象进行排序或比较等操作,并且不依赖于任何特定实例。

          6) 在第一次实例化对象之前必须进行特殊处理时。

          【讨论】:

            【解决方案8】:

            当类的客户端没有要使用的类的实例时,您可以使用静态方法。例如,单例设计模式用于确保系统中仅存在一个类的一个实例。它要求 Singleton 的构造函数是私有的,这样客户端就不能创建实例。

            如果你不能创建一个实例,你如何访问类的实例方法呢?通过调用返回类的 Singleton 实例的静态方法。

            这当然只是一种情况,但还有很多其他情况。

            【讨论】:

              猜你喜欢
              • 2016-02-15
              • 1970-01-01
              • 2011-03-23
              • 2012-09-15
              • 1970-01-01
              • 2011-01-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多