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.