繁体   English   中英

C#中的static变量有什么用? 什么时候使用它? 为什么我不能在方法内部声明 static 变量?

[英]What is the use of static variable in C#? When to use it? Why can't I declare the static variable inside method?

我在 C# 中搜索了大约 static 个变量,但我仍然不明白它的用途。 此外,如果我尝试在方法内声明变量,它不会给我这样做的权限。 为什么?

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

第二件事

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();
    }
}

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 因此静态变量值在该类的所有实例之间共享。

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

当只需要一个变量副本时,使用静态变量。 因此,如果您在方法中声明变量,则不会使用此类变量,它只会成为局部函数。

静态的例子是

class myclass
{
    public static int a = 0;
}

声明为静态的变量通常在类的所有实例之间共享。

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

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

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

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

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.Instance.LoadTexture("myImage.png");

关于您的最后一个问题:您指的是编译器错误CS0176 我试图找到更多关于它的信息,但只能找到 msdn 不得不说的内容:

即使没有创建类的实例,静态方法、字段、属性或事件也可以在类上调用。 如果创建了类的任何实例,则它们不能用于访问静态成员。 静态字段和事件只存在一份副本,静态方法和属性只能访问静态字段和静态事件。

当只需要一个副本时使用静态变量。 让我用一个例子来解释这一点:

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);
    }
}

现在我们已经为我们的class circle 创建了 2 个实例,即创建了 2 组_PI和其他变量的副本。 因此,如果我们有很多此类的实例,将创建_PI多个副本以占用内存。 因此,在这种情况下,最好将_PI等变量_PI static并对其进行操作。

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);
    }
}

现在无论为 circle class了多少个实例,变量_PI存在一个副本, _PI节省我们的内存。

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

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

class Book
{
    public static int myInt = 0;
}

public class Exercise
{
    static void Main()
    {
        Book book = new Book();
       //Use the class name directly to call the property myInt, 
      //don't use the object to access the value of property myInt

        Console.WriteLine(Book.myInt);

        Console.ReadKey();

    }
}

从这个@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(Ai); 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(Ai); Console.WriteLine(obj2.j); Console.WriteLine(obj2.s2); Console.WriteLine(A.s1); Console.ReadKey(); } }

    }

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

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

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

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

我经常使用静态(类)变量为类的每个实例分配一个唯一的实例 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 用于初始化只读属性 IID,这是该实例的唯一 ID。

我发现这很有用,因为我开发的应用程序中使用了成群的对象,并且能够跟踪已创建的对象数量以及跟踪/查询单个实例是很好的。

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

尝试使用类名Book.myInt直接调用它

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM