代码之家  ›  专栏  ›  技术社区  ›  GurdeepS

当证明静态类的合理性时,这意味着什么?

c#
  •  1
  • GurdeepS  · 技术社区  · 15 年前

    1)静态类成员可用于分离独立于任何对象标识的数据和行为:无论对象发生了什么,数据和函数都不会更改。当类中没有依赖于对象标识的数据或行为时,可以使用静态类。

    不管对象发生了什么,函数都不会改变,这意味着什么?函数如何改变?静态变量,是的,但是函数呢?

    “对象身份”是什么意思?例如,这会是一个房子对象中的特定房子吗?(所以我们要处理一个特别挑选的房子)。所以静态类不能在任何房屋对象上工作?

    2)如果我不使用实例状态,我应该始终使用静态类吗?使用实例状态的静态类和实例类有什么区别?我能想到的是静态类只能是1个实例,因此1个实例意味着如果类与实例状态一起工作(如果有线程同步),那么将有许多调用排队?显然,静态状态应该只需要一个静态类。

    这是正确的吗?

    5 回复  |  直到 15 年前
        1
  •  1
  •   Blorgbeard    15 年前

    回答问题1)

    假设你有一个汽车物体,它有一个叫做速度的场。如果创建新的汽车对象,然后使用此函数设置速度属性

    public void SetSpeed(int value)
    {
       this.speed = value
    }
    

    函数setspeed取决于正在初始化的car对象,因此它可以访问speed属性。因此,如果没有初始化的car setspeed,将无法调用。但是,如果函数是静态的,那么它就不能访问任何特定的初始化car对象,只能访问其他静态定义的对象。

    回答问题2) 静态函数不能访问任何实例声明的函数或变量,因此使用静态函数处理实例状态项是没有意义的。

        2
  •  3
  •   James    15 年前

    我倾向于将静态方法视为创建与特定类相关的辅助函数的一种方法,这样我就可以全局地使用它们,而不必实例化任何对象。一个非常简单的例子是:

    public class Person
    {
        private string name;
        private DateTime dob;
    
        public Person(string name, DateTime dob)
        {
             this.name = name;
             this.dob = dob;
        }
    
        public int Age { get { return CalculateAge(this.dob); } }
        public string Name { get { return this.name; } }
    
        public static int CalculateAge(DateTime dob)
        {
              // use dob to work out age.
        }
    
    }
    

    所以在上面的场景中,您可以看到我是否创建了一个Person对象,我可以使用一个只读属性来封装年龄的计算。但是,如果我需要根据日期计算出某人的年龄,而不是特定的Person对象,我可以使用静态方法,即。

    // object usage
    var p = new Person("Joe Bloggs", DateTime.Parse("10/11/1981"));
    Console.WriteLine(p.Age);
    
    // static usage
    Console.WriteLine(Person.CalculateAge(DateTime.Parse("10/11/1981"));
    
        3
  •  2
  •   clemahieu    15 年前

    静态方法只不过是标记到特定类的全局函数。它们主要在没有多重继承的语言中用作解决方法。

    如果您有一个根据半径计算周长的函数,并且在您的项目中需要这个函数,那么您可以创建这样的类:

    public static class geometry_facilities
    {
      public static Double circumference (Double radius)
      {
        return radius * 2 * Math.PI
      }
    }
    

    您可以通过以下方式访问此功能:

    geometry_facilities.circumference (6.730);
    

    这样做的面向对象方法是 使用static anything,而不是multiple inherit from geometry_facilities来拉入功能。静态方法主要用于只有一个继承的OO语言,以便于代码重用。

        4
  •  1
  •   Robert Harvey    15 年前

    静态类没有实例。加载程序集后,所有静态类中的所有静态方法都将立即对应用程序可用。另一种说法是,不必使用新的运算符创建静态类的实例,就可以使用该类中的方法。

    实际上,这意味着您将无法处理静态类中的状态,这本质上使方法不可变,因此线程安全。在静态方法上不会发生线程队列;所有调用都会立即执行。没有对象标识,因为正如您正确指出的,类没有多个实例可用。

    扩展方法和实用方法是静态类中静态方法的典型示例。它们通常接受一个对象,对其进行操作,并返回相同或不同类型的新对象或修改后的对象。调用之间不保持任何状态,因为正如一个海报所指出的,由于没有类实例,所以没有地方保存类变量。当方法返回时,方法中为处理目的定义的任何变量都将超出范围(丢失)。

        5
  •  1
  •   ChrisW    15 年前

    不管对象发生了什么,函数都不会改变,这意味着什么?函数如何改变?静态变量,是的,但是函数呢?

    我认为它的措辞很糟糕:与其说“静态数据和函数不管对象发生了什么都不会改变”,不如说,“静态数据和函数不会影响对象特定实例的更改,也不会受到对象特定实例的更改的影响。”

    例如,给定一个类,比如…

    public class Car
    {
      int m_speed;
      public int Speed { set { m_speed = value; } }
    }
    

    …一些静态数据和静态方法可能是这样的…

    public class Car
    {
      int m_speed;
      public int Speed { set { m_speed = Math.Max(value, s_maxSpeed; } }
      //static data and static method
      static int s_maxSpeed;
      public static void SetMaxSpeed(int maxSpeed) { s_maxSpeed = maxSpeed; }
    }
    

    …在这个例子中,静态 s_maxSpeed 值存在,静态 SetMaxSpeed 无论是否有 Car 实例甚至存在。

    “对象身份”是什么意思?例如,这会是一个房子对象中的特定房子吗?(所以我们要处理一个特别挑选的房子)。所以静态类不能在任何房屋对象上工作?

    我认为“对象标识”和“对象实例”的含义相同:它们是同义词。这个 object.ReferenceEquals 方法允许您测试对象的标识,即查看两个对象引用是否指向同一(“相同”)实例/标识。

    如果我不使用实例状态,我应该始终使用静态类吗?

    “是”(在一定程度上),因为所有内容(甚至非实例状态)都必须在某种类型(例如,静态)类中。

    使用实例状态的静态类和实例类有什么区别?我能想到的是静态类只能是1个实例,因此1个实例意味着如果类与实例状态一起工作(如果有线程同步),那么将有许多调用排队?

    一个区别是静态数据始终存在,而实例数据在创建实例之前/之前不存在。静态类类似于单例对象是正确的。

    但是,即使需要线程同步,“同步”也不会自动发生(无论是静态的还是单例的),而且在这两种情况下都必须显式地实现(例如,使用 lock 关键词等)。