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

내가 5 =하는 int 우리는 클래스의 정적으로 선언처럼
Kartik 파텔

3
VB.NET은 로컬 정적 변수를 지원합니다. 그들은 vb와의 호환성을 유지하기 위해 그것을 구현해야했습니다. 생성되는 코드의 양은 엄청나고 , 로컬 정적은 스레드로부터 안전하지 않기 때문에 어렵습니다. 필드는 스레드로부터 안전하지 않지만 모두가이를 기대합니다.
Hans Passant

당신은 당신이 원하는 정보를 ... 얻으면 가능으로 망가 마크 대답 잊지
Pranay라나를

3
Book인스턴스 ( book)를 통해 no 유형 (이 경우 )을 통해 정적 변수 / 메서드에 액세스 할 수 있으므로 더 쉬운 솔루션은 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변수를 선언합니다 . 이 코드를 실행하면 출력은 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. 따라서 정적 변수 값은 해당 클래스의 모든 인스턴스에서 공유됩니다.


9
@Pranay : 네 그게 더 나은하지만 당신은 나에게 내가 .... .... 그것은 저와 다른 사람을 위해 더 나은 cound보다 위 어쨌든 좋은 노력을 보여줄 것을 예를 보여 주면
Kartik 파텔

1
그것은 클래스에 정적입니다. 즉, 그 값은 그 값이 저장된 클래스에 충실하게 유지됩니다 ... 기다려주세요 ... class
chwi

정적 변수가 클래스의 모든 인스턴스에서 공유된다고 말했지만 인스턴스가 없으면 어떻게 될까요? 여전히 변수를 설정할 수 있습니까? 정적 클래스에 동적 데이터를 저장할 수 있습니까?
Kokodoko 2015 년

@Kokodoko, 인스턴스가 없어도 반드시 변수를 설정할 수 있습니다. 즉 정적 성격을 정의
Ladmerc

33

C #에는 정적 변수 가 전혀 없습니다 . C #을 통해 특정 유형 정의에서 정적 필드 를 선언 할 수 있습니다 . 정적 필드는 특정 유형의 모든 인스턴스와 공유되는 상태입니다. 따라서 정적 필드의 범위는 전체 유형입니다. 이것이 메서드 내에서 정적 필드를 선언 할 수없는 이유입니다. 메서드는 자체 범위이고 메서드에서 선언 된 항목은 메서드의 테두리를 통해 액세스 할 수 없어야합니다.


5
문서에서는 "정적 한정자로 선언 된 필드를 정적 변수라고합니다."로 명시되어 있습니다. msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx 하지만 나머지 설명은 맞습니다.
Teoman shipahi

19

정적 변수는 변수의 복사본이 하나만 필요한 경우에 사용됩니다. 따라서 메서드 내에서 변수를 선언하면 해당 변수를 사용하지 않고 기능 만 수행 할 수 있습니다.

정적의 예는

class myclass
{
    public static int a = 0;
}

static으로 선언 된 변수는 일반적으로 클래스의 모든 인스턴스에서 공유됩니다.

static으로 선언 된 변수는 일반적으로 클래스의 모든 인스턴스에서 공유됩니다. VariableTest 클래스의 여러 인스턴스를 만들 때이 영구 변수는 모든 인스턴스에서 공유됩니다. 따라서 주어진 시점에서 영구 변수에는 하나의 문자열 값만 포함됩니다.

모든 인스턴스에 사용할 수있는 변수의 복사본이 하나뿐이므로 this.permament 코드는 this.variablename이 인스턴스 변수 이름을 참조한다는 것을 기억할 수 있기 때문에 컴파일 오류가 발생합니다. 따라서 코드에 표시된대로 정적 변수에 직접 액세스해야합니다.


예를 들어 설명해 주시겠습니까?
Kartik Patel

하지만 클래스의 인스턴스를 만들면 정적 변수에 액세스 할 수 없습니다. 왜? 클래스의 인스턴스를 만드는 것만이 아니라 classname.variable로 정적 변수에 액세스 할 수 있습니다 .......... ......
Kartik Patel

@Kartik Patel은 정적 myInt에 액세스하기 위해 클래스 이름을 사용해야하기 때문입니다. 왜 이런지 모르겠어요. 그러나 클래스의 정적 부분에 액세스하기를 원하기 때문에 훨씬 더 명확하다고 말하고 싶습니다. 인스턴스에 액세스하기 위해 필요한 경우 정적이 아닙니다.
dowhilefor

@dowhilefor : 그러나 위에서 언급했듯이 "정적으로 선언 된 변수는 일반적으로 클래스의 모든 인스턴스에서 공유됩니다." 그럼 이것의 의미는 무엇입니까?
Kartik Patel

@Kartik Patel은 인스턴스를 사용하여 외부에서 변수에 액세스 할 수 없지만 항상 클래스 내부에서 정적 변수를 사용할 수 있으며 모든 인스턴스에서 공유됩니다. 또한이 대답을 준 것은 내가 아니라, 그냥 그것에 대해 언급하고 있습니다.
dowhilefor

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이 그것에 대해 말한 것만 찾을 수있었습니다.

클래스의 인스턴스가 생성되지 않은 경우에도 클래스에서 정적 메서드, 필드, 속성 또는 이벤트를 호출 할 수 있습니다. 클래스의 인스턴스가 만들어지면 정적 멤버에 액세스하는 데 사용할 수 없습니다. 정적 필드 및 이벤트의 복사본은 하나만 존재하며 정적 메서드 및 속성은 정적 필드 및 정적 이벤트에만 액세스 할 수 있습니다.


5

정적 변수는 복사본이 하나만 필요한 경우에 사용됩니다. 예를 들어 설명하겠습니다.

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

이제 여기에서 classcircle에 대해 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);
    }
}

이제 classcircle에 대해 얼마나 많은 인스턴스가 만들어 졌는지에 관계없이 _PI우리의 메모리를 절약 하는 변수의 복사본은 하나만 존재 합니다.


4

정적 클래스는 해당 클래스의 개체를 만들거나 인스턴스화 할 필요가 없습니다. 정적 클래스로 만들기 위해 클래스 이름 앞에 static C # 키워드를 붙일 수 있습니다.

기억하세요 : 우리는 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. 클래스 변수 VS 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

"언제 사용합니까?" 질문:

나는 종종 정적 (클래스) 변수를 사용하여 클래스의 모든 인스턴스에 고유 한 인스턴스 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

클래스 이름으로 직접 호출하십시오. Book.myInt


정확히 위에서 @Kunal 무 케르 예제를 참조
leonidaa

0

세션 변수와 비교할 때 정적 변수는 서버에 배포 된 응용 프로그램을 사용하고 있다는 것을 고려할 때 모든 사용자에게 동일한 값을 갖습니다. 두 명의 사용자가 애플리케이션의 동일한 페이지에 액세스하는 경우 정적 변수는 최신 값을 보유하고 각 사용자에 대해 다른 세션 변수와 달리 두 사용자에게 동일한 값이 제공됩니다. 따라서 응용 프로그램 코드와 함께 사용해야하는 값을 포함하여 모든 사용자에게 공통적이고 동일한 것을 원한다면 정적 만 사용하십시오.


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.