C#での静的変数の使用は何ですか?いつそれを使うのですか?メソッド内で静的変数を宣言できないのはなぜですか?


106

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

4
「静電界」という意味ですか?
Dennis

クラスstatic int i = 5で宣言するように
Kartik Patel

3
VB.NETはローカル静的変数をサポートしています。彼らはvbとの互換性を保つためにそれを実装しなければなりませんでした。それが生成するコードの量は膨大で、ローカルスタティックはスレッドセーフではないため困難です。フィールドもスレッドセーフではありませんが、誰もがそれを期待しています。
ハンスパッサント2012年

必要な情報を入手したら、回答を承認済みとしてマークすることを忘れないでください...
Pranay Rana

3
静的変数/メソッドにはBook、インスタンス(book)ではなくタイプ(この場合)を介してアクセスできるため、より簡単な解決策はBook.myIntです。
Jaider

回答:


171

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変数を宣言しているだけです。このコードを実行すると、出力は10およびになり10ます。それは簡単です。

ここで静的変数を見てみましょう。変数をとして宣言しています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();
    }
}

上記のコードを実行すると、出力は10andになり15ます。したがって、静的変数の値は、そのクラスのすべてのインスタンス間で共有されます。


9
@Pranay:はいthatsのより良いが、あなたは私に私は....それは私と他の人のために良いことcoundより上記とにかく良い努力を示した例を示している場合
Kartikパテル

1
それはクラスに対して静的です。つまり、その値は、その値が格納されているクラスに忠実なままです...待ってください...クラス
chwi

あなたは静的変数がクラスのすべてのインスタンス間で共有されていると言います...しかし、インスタンスがない場合はどうなりますか?変数を設定できますか?静的データを動的クラスに保存することはできますか?
Kokodoko 2015年

@ココドコ、インスタンスがなくても変数はきっと設定できます。それはその静的な性質を定義します
Ladmerc

33

C#には静的変数がまったくありません。C#を使用して、特定の型定義で静的フィールドを宣言できます。静的フィールドは、特定のタイプのすべてのインスタンスと共有される状態です。したがって、静的フィールドのスコープはタイプ全体です。そのため、メソッド内で静的フィールドを宣言することはできません。メソッドはそれ自体がスコープであり、メソッドで宣言されたアイテムは、メソッドの境界を越えてアクセスできないようにする必要があります。


5
まあ、ドキュメンテーションでは、「静的修飾子で宣言されたフィールドは静的変数と呼ばれます」と記載されています。msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspxしかし、説明は残ります。
Teoman Shipahi 2017年

19

静的変数は、変数のコピーが1つだけ必要な場合に使用されます。したがって、メソッド内で変数を宣言すると、そのような変数は使用されなくなり、ローカルでのみ機能するようになります。

静的の例は

class myclass
{
    public static int a = 0;
}

staticと宣言された変数は、通常、クラスのすべてのインスタンスで共有されます。

staticと宣言された変数は、通常、クラスのすべてのインスタンスで共有されます。VariableTestクラスの複数のインスタンスを作成する場合この変数パーマは、それらすべてで共有されます。したがって、任意の時点で、永続変数に含まれる文字列値は1つだけです。

すべてのインスタンスで使用できる変数のコピーは1つしかないため、this.variablenameがインスタンス変数名を参照していることが思い出されるため、コードthis.permamentはコンパイルエラーになります。したがって、コードに示されているように、静的変数は直接アクセスされます。


例で説明してもらえますか?
Kartik Patel、2012

しかし、クラスのインスタンスを作成すると、静的変数にアクセスできません。なぜですか?クラスのインスタンスを作成しないと、classname.variableで静的変数にアクセスできません。 ......
カルティックパテル

静的myIntにアクセスするにはクラス名を使用する必要があるため、@ Kartik Patel。なぜこのように、私は知りません。しかし、クラスの静的な部分にアクセスしたいので、より明確であると言えるでしょう。インスタンスにアクセスする必要がある場合、静的ではありません。
dowhile for

@dowhilefor:しかし、前述のように、「静的と宣言された変数は、クラスのすべてのインスタンス間で一般的に共有されます。」次に、これの意味は何ですか?
Kartik Patel、2012

@Kartik Patelでは、インスタンスを使用して外部から変数にアクセスすることはできませんが、クラス内で静的変数をいつでも使用でき、すべてのインスタンス間で共有されます。また、この答えを出したのは私ではなく、私はそれについてコメントしています。
dowhile for

9

静的変数の「実世界」の例:

アプリケーションのハードコードされた値に到達できるクラスを構築します。列挙型に似ていますが、データ型に柔軟性があります。

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

広く知られているシングルトン。これにより、クラスのインスタンスを1つだけ持つように制御できます。これは、アプリケーション全体でアクセスしたいが、このクラスで使用できるようにするためだけにすべてのクラスに渡さない場合に非常に役立ちます。

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がそれについて言わなければならないことを見つけることができるだけでした:

クラスのインスタンスが作成されていない場合でも、静的メソッド、フィールド、プロパティ、またはイベントはクラスで呼び出すことができます。クラスのインスタンスが作成された場合、それらを使用して静的メンバーにアクセスすることはできません。静的フィールドとイベントのコピーは1つだけ存在し、静的メソッドとプロパティは静的フィールドと静的イベントにのみアクセスできます。


5

静的変数は、そのコピーが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);
    }
}

これで、classサークルの2つのインスタンス_PI が作成されました。つまり、他の変数とともに2つのコピーのセットが作成されます。したがって、このクラスのインスタンスが多数ある場合、_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);
    }
}

classサークルのインスタンスがいくつ作成されても_PI、メモリを節約する変数のコピーは1つだけ存在します。


4

静的クラスでは、そのクラスのオブジェクトを作成してインスタンス化する必要はありません。クラス名の前に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();

    }
}

オブジェクトを使用してプロパティmyIntの値にアクセスしようとすると、エラーが発生するため、非常に良い観察です。static void Main(){Book book = new Book(); //これによりエラーが発生します:book.myInt = 5;
leonidaa

2

この@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#のインスタンス変数

    静的クラスメンバー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();
    
        }
    
    
    }

    }

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください

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


1

型のインスタンスを操作するデータメンバーと関数メンバーは、インスタンスメンバーと呼ばれます。たとえば、intのToStringメソッドはインスタンスメンバーの例です。デフォルトでは、メンバーはインスタンスメンバーです。型のインスタンスではなく、型自体を操作するデータメンバーと関数メンバーは、静的としてマークする必要があります。Test.MainメソッドとConsole.WriteLineメソッドは静的メソッドです。Consoleクラスは実際には静的クラスです。つまり、そのすべてのメンバーは静的です。実際にコンソールのインスタンスを作成することはありません。1つのコンソールがアプリケーション全体で共有されます。


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を使用して、このインスタンスの一意のIDである読み取り専用プロパティIIDを初期化します。

オブジェクトの群れが使用されるアプリケーションを開発し、作成された数を追跡したり、個々のインスタンスを追跡/照会したりできるので、これは便利です。

また、クラス変数を使用して、リアルタイムで報告できるインスタンスのプロパティの合計や平均などを追跡します。クラスは、クラスのすべてのインスタンスに関する要約情報を保持するのに適した場所だと思います。



0

セッション変数と比較すると、静的変数は、サーバーにデプロイされているアプリケーションを使用していることを考えると、すべてのユーザーに対して同じ値になります。2人のユーザーがアプリケーションの同じページにアクセスする場合、静的変数は最新の値を保持し、ユーザーごとに異なるセッション変数とは異なり、同じ値が両方のユーザーに提供されます。したがって、アプリケーションコードに沿って使用することになっている値を含め、すべてのユーザーに共通で同じものが必要な場合は、staticのみを使用してください。


0

yauは静的変数を使用するため、オブジェクトをインスタンス化する必要はありません。Console.WriteLine(Book.myInt);


-1

静的変数は、プログラムが終了するまで以前の値を保持します。staticは、class_Name.Method()またはclass_Name.Propertyを直接呼び出すことによって使用されます。オブジェクト参照は必要ありません。staticの最も一般的な使用法は、C#のMathクラスです。Math.Sin()、Math.Cos()、Math.Sqrt()。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.