2010-03-24 5 views
3

최근 C# 학습을 시작했지만 성가신 문제가 발생했습니다. 내 프로그램에서 모든 기능에 사용할 수있는 모든 변수는 모든 기능 앞에 "정적"을 넣어야합니다. 가능하다면 이것을 피하는 방법을 알고 싶습니다.C#에서 "정적"참조 제거하기

작은 측면 질문 : 함수 내부에 공용 변수를 만드시겠습니까? 전역 변수를 사용하여

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net; 
using System.Threading; 
using System.Net.Sockets; 

namespace NetworkExercise 
{ 
class Client 
{ 
    public IPAddress addr; 
    public int port; 
    public string name; 
    public Thread thread; 
    public TcpClient tcp; 
    public NetworkStream stream; 

    public Client(IPAddress addr, int port, string name, NetworkStream stream) 
    { 
    } 
} 
class Program 
{ 
    //NETWORK 
    TcpListener tcpListener; 
    Thread listenThread; 
    ASCIIEncoding encoder = new ASCIIEncoding(); 
    //DATA 
    byte[] buffer = new byte[4096]; 
    string servIp; 
    int servPort; 
    //CLIENT MANAGEMENT 
    int clientNum; 

    static void Main(string[] args) 
    { 
     beginConnect(); 
    } 
    public void beginConnect() 
    { 
     Console.Write("Server IP (leave blank if you're the host): "); 
     servIp = Console.ReadLine(); 
     Console.Write("Port: "); 
     servPort = Console.Read(); 

     tcpListener = new TcpListener(IPAddress.Any, servPort); 
     listenThread = new Thread(new ThreadStart(listenForClients)); 
     listenThread.Start(); 
    } 
    public void listenForClients() 
    { 
     tcpListener.Start(); 

     Console.WriteLine("Listening for clients..."); 

     while (true) 
     { 
      Client cl = new Client(null, servPort, null, null); 
      cl.tcp = tcpListener.AcceptTcpClient(); 
      ThreadStart pts = delegate { handleClientCom(cl); }; 
      cl.thread = new Thread(pts); 
      cl.thread.Start(); 
     } 
    } 
    public void handleClientCom(Client cl) 
    { 
     cl.stream = cl.tcp.GetStream(); 
    } 

} 

}

답변

14

는 일반적으로 :

이 내 프로그램이 지금처럼 보인다, 나는 기본적으로 모든 곳에서 "정적"을 추가 할 필요없이, 그런 식으로 유지하려는 것입니다 그들이 결합력과 손상 가능성을 증가 시키므로 나쁜 습관을 고려하기 때문에 자주 사용하는 것으로 생각하면 접근 방식을 재고해야합니다. 모든 코드가 동일한 몇 가지 변수를 사용하는 경우 시스템의 전역 상태를 추적해야하고 프로그램의 어느 부분을 수정했는지 모르기 때문에 디버깅하는 데 매우 어려움을 겪을 수 있습니다.

마찬가지로 비슷한 이유로 클래스에서 공개 입력란을 사용하지 않아야합니다. 이렇게하면 클래스의 내부 메커니즘을 변경하면 클라이언트 코드가 깨지는 등 클라이언트 코드가 클래스 구현에 직접 연결될 수 있습니다. 당신이 사용해야하는 것은 properties입니다.

질문에 대답하려면 : 아니오, 회원이 전 세계에 액세스 할 수있게하려면 정적이어야합니다. 그렇지 않으면 오브젝트에 액세스하기 위해 참조가 필요한 오브젝트에만 존재합니다.

여기에서 읽을 수있는 주요 아이디어는 dependency injectionencapsulation입니다. 홈페이지에서

+0

위대한 의견과 답변, 덕분에 많이! – bjrnt

0

쓰기이 :

 

static void Main(string[] args) 
{ 
Program myProgram = new Program(); 
myProgram.beginConnect(); 
} 
 
+0

그냥 기본 개념 기억 - 정적 메서드는 인스턴스와 관련이 없습니다. - 메서드를 정의하는 클래스의 인스턴스를 만들지 않는 한 비 정적 메서드에 직접 액세스 할 수 없습니다 (메서드는 public으로 선언해야 함) – RockWorld

2

의 주요 기능에 Program 클래스의 인스턴스를 만들어보십시오. 마찬가지로 :

Program program = new Program(); 

는 그런 다음 같은 멤버 함수에 액세스 할 수 있습니다

program.beginConnect(); 
1

당신이 이해하기 정말 중요하다 근본적인 무언가에 명중 한의 '정적'키워드는 어떻게 무엇을 의미 및 않습니다 나는 그것을 올바르게 사용 하는가? 얼마나 많은 사람들이이 질문에 올바르게 대답 할 수 없는지 놀랄 것입니다.

Rakesh가 언급 한 것처럼 컴파일러는 beginConnect가 인스턴스 메서드이기 때문에 컴파일러에서 'beginConnect'메서드를 정적으로 표시해야합니다. 즉, 메서드를 호출하기 위해 개체의 인스턴스가 필요합니다. 그의 예제는 tafa의 답과 동일하게 작동합니다. 단지 Program의 인스턴스를 만들고, 로직 (메서드 및 속성)을 별도의 클래스에 넣고, 해당 클래스의 인스턴스를 만든 다음 메소드를 호출하십시오.

'정적'을 연구하고 이해하는 동안 정적 유형과 참조 유형의 차이점을 확실하게 이해하는 것이 좋습니다.