Избавляемся от «статических» ссылок в C # - PullRequest
3 голосов
/ 24 марта 2010

Я недавно начал изучать C #, но столкнулся с досадной проблемой. Каждая переменная, которую я хочу, доступна всем функциям в моей программе, я должен поставить «static» перед каждой функцией. Я хотел бы знать, как избежать этого, если это возможно?

Кроме того, небольшой побочный вопрос: создание открытых переменных внутри функций?

Вот так выглядит моя программа прямо сейчас, и я хочу в основном сохранить ее так, без необходимости везде добавлять "static":

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

}

}

Ответы [ 4 ]

14 голосов
/ 24 марта 2010

Использование глобальных переменных, как правило, считается плохой практикой, так как они увеличивают связность и ремонтопригодность, поэтому вам следует пересмотреть свой подход, если вы часто используете их. Если во всем вашем коде используются одни и те же несколько переменных, вам может быть очень сложно отладить его, поскольку вам нужно отслеживать глобальное состояние системы, и вы не знаете, какая часть программы его модифицировала.

Кроме того, вы почти никогда не должны использовать открытые поля в классах по аналогичным причинам. Это позволяет клиентскому коду быть привязанным непосредственно к реализации вашего класса, так что, если вы измените внутреннюю механику класса, клиентский код нарушится. То, что вы должны использовать, это свойства .

Однако, чтобы ответить на ваш вопрос: нет, если вы хотите, чтобы участник был глобально доступен, он должен быть статическим. В противном случае он существует только для объекта, на который вам потребуется ссылка для доступа к нему.

Вот некоторые ключевые идеи, о которых вы можете прочитать здесь: внедрение зависимостей и инкапсуляция .

2 голосов
/ 24 марта 2010

Попробуйте создать экземпляр класса Program в основной функции.Как:

Program program = new Program();

Затем вы можете получить доступ к функциям-членам, например:

program.beginConnect();
1 голос
/ 25 марта 2010

Вы столкнулись с чем-то фундаментальным, что действительно важно понять, что означает ключевое слово «static» и как я правильно его использую? Вы будете удивлены, как много людей не могут правильно ответить на этот вопрос.

Как уже упоминал Ракеш, компилятор просит вас пометить ваш метод 'beginConnect' как статический, потому что beginConnect - это метод экземпляра, т.е. вам требуется экземпляр объекта для вызова метода. Его пример работает (так же, как и ответ tafa), я бы просто добавил, что он не «чувствует» правильно создавать экземпляр Program, помещать логику (методы и свойства) в отдельный класс, затем создавать экземпляр этого класса вызовите метод.

Пока вы исследуете и получаете представление о «статическом», я настоятельно рекомендую также получить четкое представление о разнице между статическим типом и ссылочным типом.

0 голосов
/ 24 марта 2010

Напишите это в основном:


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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...