在C#中使用静态变量有什么用?什么时候用?为什么我不能在方法中声明静态变量?

时间:2012-05-29 08:22:58

标签: c# static static-variables

我在C#中搜索过静态变量,但我仍然没有得到它的用途。另外,如果我尝试在方法中声明变量,它将不会授予我执行此操作的权限。为什么呢?

我见过一些关于静态变量的例子。我已经看到我们不需要创建类的实例来访问变量,但这还不足以理解它的用途以及何时使用它。

第二件事

class Book
{
    public static int myInt = 0;
}

public class Exercise
{
    static void Main()
    {
        Book book = new Book();

        Console.WriteLine(book.myInt); // Shows error. Why does it show me error?
                                       // Can't I access the static variable 
                                       // by making the instance of a class?

        Console.ReadKey();
    }
}

13 个答案:

答案 0 :(得分:157)

static变量在该类的所有实例中共享它的值。

未声明静态的示例:

public class Variable
{
    public int i = 5;
    public void test()
    {
        i = i + 5;
        Console.WriteLine(i);
    }
}


public class Exercise
{
    static void Main()
    {
        Variable var = new Variable();
        var.test();
        Variable var1 = new Variable();
        var1.test();
        Console.ReadKey();
    }
}

说明:如果你看一下上面的例子,我只是声明int变量。当我运行此代码时,输​​出将为1010。很简单。

现在让我们看一下静态变量;我将变量声明为static

静态变量示例:

public class Variable
{
    public static int i = 5;
    public void test()
    {
        i = i + 5;
        Console.WriteLine(i);
    }
}


public class Exercise
{
    static void Main()
    {
        Variable var = new Variable();
        var.test();
        Variable var1 = new Variable();
        var1.test();
        Console.ReadKey();
    }
}

现在,当我运行上面的代码时,输​​出将是1015。因此静态变量值在该类的所有实例之间共享。

答案 1 :(得分:31)

C#根本没有静态变量。您可以通过C#在特定类型定义中声明静态字段。静态字段是一种状态,与特定类型的所有实例共享。因此,静态字段的范围是整个类型。这就是为什么你不能在方法中声明静态字段的原因 - 方法本身就是一个范围,方法中声明的项目必须在方法的边界上不可访问。

答案 2 :(得分:17)

当只需要一个变量副本时,使用

静态变量。因此,如果你在方法中声明变量,就不会使用这样的变量,它只会变成局部函数..

静态的例子是

class myclass
{
    public static int a = 0;
}

声明为static的变量通常在类的所有实例中共享。

声明为static的变量通常在类的所有实例中共享。当您创建VariableTest类的多个实例时,将在所有这些变量中共享此变量permanent。因此,在任何给定的时间点,永久变量中只包含一个字符串值。

由于只有一个变量副本可用于所有实例,因此代码this.permament将导致编译错误,因为可以回想一下this.variablename是指实例变量名称。因此,静态变量将直接访问,如代码所示。

答案 3 :(得分:9)

静态变量的一些“真实世界”示例:

构建一个类,您可以在其中获取应用程序的硬编码值。与枚举类似,但数据类型具有更大的灵活性。

public static class Enemies
{
    public readonly static Guid Orc = new Guid("{937C145C-D432-4DE2-A08D-6AC6E7F2732C}");
}

广为人知的单例,这允许控制只有一个类的实例。如果您希望在整个应用程序中访问它,但是不将它传递给每个类只是为了允许这个类使用它,这非常有用。

public sealed class TextureManager
    {
        private TextureManager() {}
        public string LoadTexture(string aPath);

        private static TextureManager sInstance = new TextureManager();

        public static TextureManager Instance
        {
            get { return sInstance; }
        }
    }

这就是你如何调用texturemanager

TextureManager.Instance.LoadTexture("myImage.png");

关于你的上一个问题: 您正在引用编译器错误CS0176。我试图找到更多的信息,但只能找到msdn对它的评价:

  

静态方法,字段,属性或事件甚至可以在类上调用   当没有创建类的实例时。如果有任何实例   该类是创建的,它们不能用于访问静态   会员。只存在静态字段和事件的一个副本,并且是静态的   方法和属性只能访问静态字段和静态   事件

答案 4 :(得分:3)

静态类不要求您创建该类的对象/实例化它们,您可以在类名前面加上C#关键字static,以使其成为静态。

请记住:我们没有实例化Console类,String类,Array Class。

layer {

  bottom: "conv1_2"
  top: "conv1_2"
  name: "conv1_2_bn"
  type: "BN"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 1
    decay_mult: 0
  }
  bn_param {
    scale_filler {
      type: "constant"
      value: 1
    }
    shift_filler {
      type: "constant"
      value: 0.001
    }
 }
}

答案 5 :(得分:1)

对类型实例进行操作的数据成员和函数成员 被称为实例成员。 int的ToString方法(例如)是实例成员的示例。默认情况下,成员是实例成员。 不在类型实例上操作的数据成员和函数成员,而是在类型本身上操作,必须标记为静态。 Test.Main和Console.WriteLine方法是静态方法。 Console类实际上是一个静态类,这意味着它的所有成员都是静态的。您永远不会实际创建控制台的实例 - 在整个应用程序中共享一个控制台。

答案 6 :(得分:1)

回应"什么时候使用它?"问题:

我经常使用静态(类)变量为类的每个实例分配唯一的实例ID。我在每个类中使用相同的代码,这很简单:

//Instance ID ----------------------------------------
    // Class variable holding the last assigned IID
    private static int xID = 0;
    // Lock to make threadsafe (can omit if single-threaded)
    private static object xIDLock = new object();
    // Private class method to return the next unique IID 
    //  - accessible only to instances of the class
    private static int NextIID()                    
    {
        lock (xIDLock) { return ++xID; }
    }
    // Public class method to report the last IID used 
    // (i.e. the number of instances created)
    public static int LastIID() { return xID; }
    // Instance readonly property containing the unique instance ID
    public readonly int IID = NextIID();
//-----------------------------------------------------

这说明了关于静态变量和方法的几点:

  1. 静态变量和方法与类相关联,而不是与类的任何特定实例相关联。
  2. 可以在实例的构造函数中调用静态方法 - 在这种情况下,静态方法NextIID用于初始化readonly属性IID,它是此实例的唯一ID。
  3. 我发现这很有用,因为我开发了一些应用程序,其中使用了大量的对象,并且能够跟踪创建的数量以及跟踪/查询单个实例是很好的。

    我还使用类变量来跟踪可以实时报告的实例属性的总数和平均值等内容。我认为该类是保存关于该类所有实例的摘要信息的好地方。

答案 7 :(得分:1)

从这个@Kartik Patel示例开始,我做了一些更改,也许现在对静态变量更加清楚了

 public class Variable
    {
        public static string StaticName = "Sophia ";
        public string nonStName = "Jenna ";
        public void test()
        {
            StaticName = StaticName + " Lauren"; 
            Console.WriteLine("  static ={0}",StaticName);
            nonStName = nonStName + "Bean ";
            Console.WriteLine("  NeStatic neSt={0}", nonStName);

        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Variable var = new Variable();
            var.test();
            Variable var1 = new Variable();
            var1.test();
            Variable var2 = new Variable();
            var2.test();
            Console.ReadKey();

        }
    }

Output 
  static =Sophia  Lauren
  NeStatic neSt=Jenna Bean
  static =Sophia  Lauren Lauren
  NeStatic neSt=Jenna Bean
  static =Sophia  Lauren Lauren Lauren
  NeStatic neSt=Jenna Bean
  1. C#中的类变量VS实例变量

    静态类成员C#OR类变量

    class A
    {
        // Class variable or " static member variable"  are declared with 
        //the "static " keyword
    
        public static int i=20;
        public int j=10;         //Instance variable 
        public static string s1="static class variable"; //Class variable 
        public string s2="instance variable";        // instance variable 
    }
    class Program
    {
        static void Main(string[] args)
        {
            A obj1 = new A();
    
            // obj1 instance variables 
            Console.WriteLine("obj1 instance variables ");
            Console.WriteLine(A.i);
            Console.WriteLine(obj1.j);
            Console.WriteLine(obj1.s2);
            Console.WriteLine(A.s1);
    
            A obj2 = new A();
    
            // obj2 instance variables 
            Console.WriteLine("obj2 instance variables ");
            Console.WriteLine(A.i);
            Console.WriteLine(obj2.j);
            Console.WriteLine(obj2.s2);
            Console.WriteLine(A.s1);
    
            Console.ReadKey();
    
        }
    
    
    }
    

    }

enter image description here enter image description here enter image description here enter image description here

https://en.wikipedia.org/wiki/Class_variable

https://en.wikipedia.org/wiki/Instance_variable

https://en.wikipedia.org/wiki/Static_variable

https://javaconceptoftheday.com/class-variables-and-instance-variables-in-java/?fbclid=IwAR1_dtpHzg3bC5WlGQGdgewaTvuOI6cwVeFUtTV8IZuGTj1qH5PmKGwX0yM

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members

答案 8 :(得分:1)

仅需要一个副本时使用静态变量。让我用一个例子解释一下:-

class circle
        {
           public float _PI =3.14F;
           public int Radius;


           public funtionArea(int radius)
            {
                return this.radius * this._PI      
            }

        }
    class program
    {
      public static void main()
      {
       Circle c1 = new Cirle();
       float area1 = c1.functionRaduis(5);

       Circle c2 = new Cirle();
       float area2 = c1.functionRaduis(6);

      }

    }

现在我们在类循环中创建了2个实例,即创建了_PI的2套副本以及其他变量。假设如果我们有很多此类的实例,将创建_PI的多个副本占用内存,因此在这种情况下,最好使诸如_PI这样的变量静态并对其进行操作。

    class circle
        {
           static float _PI =3.14F;
           public int Radius;


           public funtionArea(int radius)
            {
                return this.radius * Circle._PI      
            }

        }
    class program
    {
      public static void main()
      {
       Circle c1 = new Cirle();
       float area1 = c1.functionRaduis(5);

       Circle c2 = new Cirle();
       float area2 = c1.functionRaduis(6);

      }

    }

现在,无论为类循环创建多少个实例,变量_PI都只存在一个副本,从而节省了内存。

答案 9 :(得分:0)

尝试使用类名Book.myInt

直接调用它

答案 10 :(得分:0)

与会话变量进行比较时,考虑到我正在使用部署在服务器中的应用程序,静态变量将对所有用户具有相同的值。如果两个用户访问应用程序的同一页面,则静态变量将保留最新值,并且将向两个用户提供相同的值,而不像每个用户不同的会话变量。因此,如果您想为所有用户提供一些共同的东西,包括应该在应用程序代码中使用的值,那么只使用静态。

答案 11 :(得分:0)

您不需要实例化对象,因为yau将使用 静态变量: Console.WriteLine(Book.myInt);

答案 12 :(得分:-1)

静态变量在程序退出之前保留其先前的值。通过直接调用class_Name.Method()或class_Name.Property来使用Static。不需要对象引用。最常用的静态是C#的Math类。 Math.Sin(),Math.Cos(),Math.Sqrt()。