views:

282

answers:

4

Hello. I've recently begun learning C# but have encountered an annoying problem. Every variable I want available to all functions in my program I have to put a "static" in front of and also every function. What I'd like to know is how to avoid this, if possible?

Also, small side question: creating public variables inside functions?

This is what my program looks like right now, and I want to basically keep it like that, without having to add "static" everywhere:

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();
    }

}

}

+11  A: 

Using global variables is generally considered bad practice as they increase coupling and damage maintainability, so you should rethink your approach if you find yourself using them often. If all of your code uses the same few variables, you can have a very difficult time debugging it, since you have to track the global state of the system and you've no idea which part of the program has been modifying it.

Also, you should almost never use public fields in classes, for similar reasons. Doing so allows client code to become tied directly into the implementation of your class such that if you change the class's internal mechanics then the client code breaks. What you should be using is properties.

To answer your question, though: no, if you want a member to be globally accessible, it must be static. Otherwise it exists only an object, to which you would need a reference in order to access it.

Some key ideas you might want to read about here are dependency injection and encapsulation.

Will Vousden
Great feedback and answer, thanks a lot!
DevEight
A: 

Write this in Main:


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

Rakesh Gunijan
Just Remember basic concept - Static methods are not instance specific. - You cannot access non static method directly unless you create instance of class defining the method (method must be declared public)
Rakesh Gunijan
+2  A: 

Try creating an instance of Program class in the main function. Like:

Program program = new Program();

Then you can access the member functions, like:

program.beginConnect();
tafa
+1  A: 

You have hit on something fundamental that is really important to understand, what does the 'static' keyword mean and how do I use it correctly? You will be surprised how many people cannot answer this question correctly.

As Rakesh has mentioned, the compiler is asking you to mark your 'beginConnect' method as static because beginConnect is an instance method, ie you require an instance of the object in order to call the method. His example works (same as tafa's answer), I would just add that it doesn't 'feel' right to create an instance of Program, put the logic (methods and properties) into a separate class, create an instance of that class then call the method.

While you are researching and getting an understanding of 'static' I strongly recommend also getting a solid understanding of the difference between a static type and a reference type.

wallismark