我最近开始学习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();
}
}
}
答案 0 :(得分:14)
使用全局变量通常被认为是不好的做法,因为它们会增加耦合并损害可维护性,因此如果您经常使用它们,则应重新考虑您的方法。如果你的所有代码都使用相同的几个变量,那么你可能很难调试它,因为你必须跟踪系统的全局状态,而你不知道程序的哪个部分已经修改它。
此外,出于类似的原因,您几乎不应该在类中使用公共字段。这样做允许客户端代码直接绑定到类的实现中,这样如果更改类的内部机制,则客户端代码会中断。你应该使用的是properties。
要回答您的问题,但是:不,如果您希望成员可以全局访问,则必须是静态的。否则它只存在于一个对象上,您需要一个引用才能访问它。
您可能希望在此处阅读的一些重要提示是dependency injection和encapsulation。
答案 1 :(得分:2)
尝试在main函数中创建Program
类的实例。像:
Program program = new Program();
然后您可以访问成员函数,例如:
program.beginConnect();
答案 2 :(得分:1)
您已经找到了一些非常重要的基本知识,“静态”关键字的含义是什么以及如何正确使用它?你会惊讶地发现有多少人无法正确回答这个问题。
正如Rakesh所提到的,编译器要求您将'beginConnect'方法标记为静态,因为beginConnect是一个实例方法,即您需要该对象的实例才能调用该方法。他的示例有效(与tafa的回答相同),我只想补充一点,创建一个Program实例并不“正确”,将逻辑(方法和属性)放入一个单独的类中,然后创建该类的实例打电话给方法。
当您正在研究并了解'静态'时,我强烈建议您也要充分了解静态类型和引用类型之间的区别。
答案 3 :(得分:0)
在Main中写下:
static void Main(string[] args)
{
Program myProgram = new Program();
myProgram.beginConnect();
}