2010-03-24 52 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的实例并不“感觉”正确,将逻辑(方法和属性)放入一个单独的类中,然后创建该类的一个实例调用该方法。

当你正在研究和理解'静态'时,我强烈建议也对静态类型和引用类型之间的区别有深入的了解。