Это глупо / не рекомендуется организовывать C# экземпляров объекта в stati c "глобальный" класс - PullRequest
1 голос
/ 29 января 2020

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

Ниже я создал пример того, что я имею в виду под «c объектами», который имеет все «аспекты» того, что будет делать моя программа. Если вам хочется помочь мне понять внедрение зависимостей, и это не слишком большая работа, тогда вы можете попробовать изменить мой пример, чтобы вместо этого использовать внедрение зависимостей (и если вы это сделаете, я был бы очень рад, поскольку это помогло бы мне научиться чему-то, что я » у меня проблемы с)

class Program
    {
        static void Main(string[] args)
        {
            Global.worker = new Worker();
            Global.employer = new Employer();
            Global.reporter = new Reporter();

            Global.worker.JobDone += Global.reporter.onWorkDoneR;
            Global.worker.JobDone += Global.employer.onWorkDoneE;

            Global.reporter.msgToUser("Initialization successful!!!");
            Global.employer.startWorkDay();

            Console.ReadLine();
        }
    }

    static class Global
    {
        static public Worker worker;
        static public Employer employer;
        static public Reporter reporter;
    }

    class Worker
    { 
        public delegate void EventHandler(object sender, ReporterArgs args);
        public event EventHandler JobDone;

        public void doJob(int joblength)
        {
            Global.reporter.msgToUser("Worker reporting that I'm starting work!!!");
            System.Threading.Thread.Sleep(joblength*1000);
            JobDone?.Invoke(this, new ReporterArgs("Work is done"));
        }
    }

    class Employer
    {
        private int jobiteration = 1;
        public void startWorkDay()
        {
            Global.worker.doJob(jobiteration);
        }

        public void onWorkDoneE(object sender, EventArgs args)
        {
            jobiteration++;
            Global.worker.doJob(jobiteration);
        }
    }

    class Reporter
    {
        public void msgToUser(string message)
        {
            Console.WriteLine(message);
        }

        public void onWorkDoneR(object sender, ReporterArgs args)
        {
            Console.WriteLine("{0} reporting: {1}", sender, args.Str);
        }
    }

    public class ReporterArgs : EventArgs
    {
        private readonly string str;

        public ReporterArgs(string str2lol)
        {
            this.str = str2lol;
        }

        public string Str
        {
            get { return this.str; }
        }
    }

1 Ответ

1 голос
/ 29 января 2020

Прежде всего, вы обязательно должны прочитать больше ссылок о классах в C#.

Глядя на код, первое, что я вижу, это то, как класс Employer обращается к Worker.

public void startWorkDay()
{
    Global.worker.doJob(jobiteration);
}

Вместо доступа к рабочему объекту stati c, вы можете обращаться с любым Worker независимый объект с этим фрагментом кода:

public void startWorkDay(Worker workerObjectToPerformTheJob)
{
    workerObjectToPerformTheJob.doJob(jobiteration);
}

Также мы не пишем C#:

static public Worker worker;
static public Employer employer;
static public Reporter reporter;

Правильный путь: public static Foo bar;


О классах и объектах:

Ваша программа выполняется в области действия static void Main(string[] args) {//stuff happens here} Поэтому, когда объект, определенный в границах Main (), хочет получить доступ к другому объекту из той же области действия , нет необходимости определять второй класс c.

Теперь, с другой стороны, что если бы было больше классов или областей? Как мы можем соединить их, чтобы они могли надежно обращаться друг к другу? Здесь у нас есть два класса, foo и bar. Foo необходимо передать строковую переменную в bar.

class foo{ string myString; }
class bar
    { 
        void myMethod(string value) 
        { print(value); } 
    }

Foo и Bar находятся в двух разных областях, поэтому для передачи myString в myMethod () мы можем реализовать мост между ними.

static class Bridge 
{
    public string passThis;
}

В области 1 ( возможно, это было событие, которое было вызвано до создания объекта бара ), создается объект Foo. Этот объект Foo передает myString в переменную Bridge.passThis.

В области 2 создается объект Bar. Bar не может получить доступ к объекту Foo, поэтому мы не можем получить доступ к objectFoo.myString. Вместо этого мы получаем доступ к Bridge.passThis и выполняем myMethod(Bridge.passThis);

Надеюсь, это кому-нибудь поможет.

...