2009-05-21 2 views
8

저는 스크립팅 언어에 익숙합니다. PHP, Javascript 등. 그리고 비교적 간단한 Java 및 C# 응용 프로그램을 작성했습니다. 이것은 내가 반복적으로 답을 필요로하는 질문이고, 나는 단 하나만이 아니라고 상상한다.전역 변수없이 데이터를 유지하는 방법은 무엇입니까?

내가 자바 스크립트에 있다고 가정 해 보겠습니다.

GUI를 통해 호출되는 함수 A()가 있는데,이 함수는 값을 가져옵니다.

GUI에 의해 호출되는 B() 함수는 값을 요구하지만 B() 함수는 A() 이후 임의의 시간만큼 호출됩니다.

A()가 매번 값을 다시 계산하기를 원하지 않습니다.

로그온 자격 증명의 예입니다. A()는 사용자 이름을 묻고 B()는 호출 할 때마다 해당 값을 사용하여 로그에 추가합니다.

이 경우 전 세계 변수를 사용하기 만합니다.

이제 C#. 전역 변수가 없습니다! 어떻게해야합니까?

편집 : 답변을 즐기고 있지만 "전체를 사용하지 마십시오"라는 댓글이 많이 있습니다. 나는 이해하지만이 요구 사항에 대한 대체 패턴을 듣고 싶습니다.

+2

함수의 출력 내용을 기억하고 나중에 다시 계산하지 않고 다시 사용하는 일반적인 기술의 이름 인 "memoization"을 읽는 것이 좋습니다. 효율적인 메모 작성을위한 흥미로운 기술이 많이 있습니다. –

답변

4

먼저 글로벌이 필요한지 자주 묻습니다. 종종 그렇지 않습니다. 당신이 정말로 하나 ...

이 몇 가지 눈에 띌라는 이름의 클래스의 정적 속성을 가지고있다 할 수있는 가장 좋은 방법을 가지고있는 경우, 그것은 효과적으로 전역 변수

public class Credentials 
{ 
    public static string Username {get;set;} 
} 

//...somewhere in your code 

Credentials.Username = "MyUserName"; 

편집된다 :

여기에 몇 명의 사람들이 글로벌 변수가 좋지 않다는 담요 진술을 말했고, 나는이 정서에 동의하며 C#의 설계자도 동의하지 않는 것으로 나타났습니다.

그러나 우리는 왜 전역 변수가 나쁜지 살펴보고 캡슐화 규칙을 위반하기 때문에 대부분이 나쁜 것으로 간주됩니다. 그러나 정적 데이터는 필수적으로 좋지 않습니다. 정적 데이터에 대한 좋은 점은 캡슐화 할 수 있다는 것입니다. 위 예제는 매우 단순한 예제입니다. 실제 시나리오에서는 정적 데이터를 같은 클래스에 포함 할 것입니다. 다른 것들은 자격 증명, 아마도 로그인 클래스 또는 사용자 클래스 또는 귀하의 응용 프로그램에 맞는 것이면 모두 작동합니다.

+0

강력하게 강조 할 것입니다 : 전역 변수를 사용하지 마십시오. 그러나 당신이 주장한다면, 이것은 좋은 방법입니다. –

+0

@Marcel : C#에 전역 변수가 없습니다. – Brian

+0

Tim에게 감사드립니다. Marcel -이 요구 사항에 대해 내가 대신 제안한 점은 무엇입니까? – ChristianLinnell

0

C#에서 전역 변수와 비슷한 동작을 얻는 방법 중 하나는 정적 클래스 메서드와 클래스 변수를 사용하는 것입니다. 정적 클래스 메서드 및 변수는 C#에서 단일 인스턴스를 가지며 다른 언어의 전역 변수와 비슷합니다.

그건 그렇고, 당신의 문제 때문에, 그것은 디자인 문제와 훨씬 비슷해 보입니다. C#은 객체 지향 디자인에 중점을 둡니다. 더 나은 OOD로 문제를 해결할 수 있다고 생각한 문제가 의심 스럽습니다.

5

이것은 좋은 방법이 아닙니다,하지만 당신이 정말로 필요하면, 여러 가지 방법이 있습니다 :

  1. 웹 애플리케이션 : 당신은 세션 등, 상황의 어떤 종류에 변수를 넣을 수 있습니다 응용 범위.
  2. 데스크톱 응용 프로그램 : 개체를 만들고 항상 개체가 활성 상태 인 클래스의 속성으로 저장할 수 있습니다.
  3. 모든 종류의 앱 : public static 속성을 사용합니다. 모든 사람에게 보입니다.
+0

답변 해 주셔서 감사합니다. 그럼 대신 좋은 행동을 제안 하시겠습니까? – ChristianLinnell

+0

선택한 언어의 디자인 패러다임과 잘 조화되도록 디자인을 변경하십시오! – tomfanning

0

함수 A는 클래스의 일부 (C라고 함)입니다. 그런 다음 함수 A는 로그온 자격 증명을 저장하고 자격 증명을 얻기위한 함수 (또는 C#의 속성)를 제공 할 수 있습니다. 필요할 때, 등록 정보를 사용하여 저장된 자격 증명을 가져 와서 다른 클래스의 Function B로 전달할 수 있습니다.

class C 
{ 
    public void functionA() 
    { 
     credentials = obtainCredentials; 
    } 

    private LogonCredentials _logonCredentials = null; 

    public LogonCredentials logonCredentials 
    { 
     get { return _logonCredentials; } 
    } 
} 

class D 
{ 
    public void functionB(LogonCredentials credentials) 
    { 
     //do stuff 
    } 
} 

///other stuff 
///other function ... 
    ... 
    instanceC = C(); 
    instanceC.functionA(); 
    ///more stuff here 
    instangeD = D(); 
    instanceD.functionB(instanceC.logonCredentials); 
1

아마도 Singleton Pattern을 사용해야합니다.

멀티 스레드 응용 프로그램을 사용하려면 싱글 톤 인스턴스의 속성에 대한 액세스가 스레드 세이프인지 확인해야합니다.

항상 응용 프로그램에 모든 종류의 전역을 소개하는 것에 대해 신중히 생각해보십시오. 그러나 사용하기를 꺼려하지 마십시오. 예를 들어 App.Settings와 같이 많은 것은 사실상 전역 적입니다. "나쁜"것도 없습니다.

article on MSDN은 C#에서 싱글 톤을 올바르게 만드는 방법을 설명합니다.

+2

@Jorge, 존경심이 나쁜 충고입니다. 싱글 톤은 정적 데이터에만 사용되어서는 안되며, 싱글 톤 패턴에 대한 요구 사항은 실제로 사람들이 생각하는 것보다 희귀합니다. 리소스 사용을 제한하고 메소드 호출이 일관된 상태를 요구하는지 확인하는 것입니다. . –

+0

이론적으로는 사실 인 것으로 나타 났지만 실제로는 유용합니다. 그들은 게으른 instanstiation, 일반적인 액세스 포인트, 그리고 추상 수준의 필요성을 기본적으로 제공합니다. 실용적인면에서 나는 어쨌든 내 자신을 사용합니다. –