C #에서 전역 변수를 사용하는 방법?


101

모든 클래스 (* .cs)가 인스턴스 참조없이 해당 콘텐츠에 액세스 할 수 있도록 변수를 선언하려면 어떻게해야합니까?

답변:


123

에서는 C#진정한 전역 변수를 정의 할 수 없습니다 (클래스에 속하지 않는다는 의미에서).

이 기능을 모방하는 가장 간단한 방법 static class은 다음과 같이 를 사용하는 것입니다.

public static class Globals
{
    public const Int32 BUFFER_SIZE = 512; // Unmodifiable
    public static String FILE_NAME = "Output.txt"; // Modifiable
    public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}

그런 다음 코드에서 정의 된 값을 검색 할 수 있습니다 (동일한 부분 인 경우 namespace).

String code = Globals.CODE_PREFIX + value.ToString();

다른 네임 스페이스를 처리하기 위해 다음 중 하나를 수행 할 수 있습니다.

  • Globals특정 클래스에 포함하지 않고 클래스를 선언하여 namespace글로벌 애플리케이션 네임 스페이스에 배치합니다.
  • 다른에서 변수를 검색하려면 적절한 using 지시문을 삽입하십시오 namespace.

@Zarathos 클래스도 정적이어야합니까?
kosnkov 2015 년

4
꼭 필요한 것은 아니지만 인스턴스화해야하는 이유를 모르겠습니다.
Tommaso Belluzzo 2015 년

당신은 더 이상 없습니다 "글로벌"응용 프로그램 상태의 일부는 당 정의를 인스턴스화해야하는 경우
바이킹

안녕하세요, 클래스에 정적 키워드를 입력하지 않으면 어떤 차이가 있습니까? FILE_NAME 문자열을 정적으로 만들었을 뿐이며 시도했지만 여전히 작동했습니다.
Tomer Cahal

1
정적 속성이 없으면 클래스를 인스턴스화 할 수 있습니다 (Globals g = new Globals ()). 내부에 선언 된 정적 변수의 동작을 변경하지는 않지만 실제로 유용하지 않습니다.
Tommaso Belluzzo

74

C #에는 전역 변수와 같은 것이 없습니다. 기간.

원하는 경우 정적 멤버를 가질 수 있습니다.

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}

동의하지만 C #에 전역 변수가없는 이유를 확장 해 주시겠습니까? 나는 static당신이 제공 한 바로 그 예제가 실제로 글로벌 변수로 간주 될 수없는 좋은 이유를 생각하고있었습니다 .
cregox 2013

3
@cawas는 "전역 변수"(아무데도 매달려 있지 않고, 어떤 클래스에도 속하지 않고 림보에 떠있는)라는 개념 자체가 OOP의 본질에 반하기 때문입니다. C #은 엄격하게 객체 지향적입니다.
Federico Berasategui

예, 그게 제가 동의하는 모든 개념입니다. 하지만 정적 멤버를 만들어서 일종의 전역 변수를 만들었습니다. 그것이 존재하지 않는다고 말한 전역 변수와 어떻게 다른가요? 실용적인 예를보고 싶습니다.
cregox 2013

1
당신이 내 질문을 회피하고 있거나 명확하지 않은 것 같습니다. 그러나 나는 이미 대답을 얻었습니다. 여기 : stackoverflow.com/a/20010543/274502
cregox 2013

7
이제 내가 의미하는 바는 정적 멤버가 개념적으로 그리고 실질적으로 전역 변수 라는 것입니다 ( 안전하지 않은 코드를 작성하거나 관리되지 않는 코드와 일종의 무거운 상호 운용을 수행하지 않는 한 차이를 만드는 힙을 제외하고 ). 그래서 왜 누군가 " csharp에는 전역 변수와 같은 것이 없습니다 "라고 말할 수 있는지 모르겠습니다 . 그것은 나를 많이 혼란스럽게했다.
cregox 2013

23

먼저 소프트웨어 아키텍처를 고려하지 않고 노골적으로 사용하는 대신 전역 변수가 정말로 필요한지 조사하십시오.

테스트를 통과했다고 가정합시다. 사용법에 따라 Globals는 경쟁 조건 및 기타 많은 "나쁜"으로 디버그하기 어려울 수 있습니다. 그런 나쁜 일을 처리 할 준비가 된 각도에서 접근하는 것이 가장 좋습니다. 그래서,

  1. 이러한 모든 전역 변수를 단일 static클래스 로 래핑합니다 (관리 용이성).
  2. 필드 (= '변수') 대신 속성이 있습니다. 이렇게하면 향후 Globals에 대한 동시 쓰기 문제를 해결할 수있는 몇 가지 메커니즘이 있습니다.

이러한 클래스의 기본 개요는 다음과 같습니다.

public class Globals
{
    private static bool _expired;
    public static bool Expired 
    {
        get
        {
            // Reads are usually simple
            return _expired;
        }
        set
        {
            // You can add logic here for race conditions,
            // or other measurements
            _expired = value;
        }
    }
    // Perhaps extend this to have Read-Modify-Write static methods
    // for data integrity during concurrency? Situational.
}

다른 클래스의 사용 (동일한 네임 스페이스 내)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;

4

이에 대한 유용한 기능은 using static

다른 사람들이 말했듯이 글로벌 클래스를 만들어야합니다.

public static class Globals {
    public const float PI = 3.14;
}

그러나 더 이상 정적 속성 앞에 클래스 이름을 쓰지 않기 위해 다음과 같이 가져올 수 있습니다.

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.