2010-03-24 21 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 2010-03-24 10:33:03

0

寫這篇文章主要:

 

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

只記得基本概念 - 靜態方法不是實例特定的。 - 除非創建定義方法的類的實例,否則不能直接訪問非靜態方法(方法必須聲明爲public) – RockWorld 2010-03-24 09:37:48

2

嘗試在主函數創建Program類的一個實例。像:

Program program = new Program(); 

然後你就可以訪問該成員的功能,如:

program.beginConnect(); 
1

你已擊中一些基本的東西是真正重要的是要了解,什麼是「靜態」關鍵字的含義及如何做我正確使用它?你會驚訝有多少人無法正確回答這個問題。

正如Rakesh所提到的,編譯器要求您將'beginConnect'方法標記爲靜態,因爲beginConnect是一個實例方法,即您需要一個實例來調用該方法。他的例子的作品(與tafa的答案相同),我只是補充說,創建一個Program的實例並不「感覺」正確,將邏輯(方法和屬性)放入一個單獨的類中,然後創建該類的一個實例調用該方法。

當你正在研究和理解'靜態'時,我強烈建議也對靜態類型和引用類型之間的區別有深入的瞭解。