简体   繁体   中英

Is it dumb/discouraged to organize C# object instances into a static “global” class

I am making a program where the objects need to chat with eachother and give orders. I'm somewhat new to C# and so I'm having trouble doing this properly. I have realized that using a static class I could achieve all I want to achieve. I understand that this is a bad approach for some reasons. I understand that I should be using dependency injection perhaps? Unfortunately I'm having trouble quite grasping how to realize that.

Below, I have created an example of what I mean by static objects that has all the "aspects" of what my program will be doing. If you feel like helping me in understanding dependency injection and it's not too much work, then you could try change my example to use dependency injection instead (and if you do, I would be very happy, as it would help me learn something I'm having trouble with)

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

First off, you should definitely read more references about classes in C#.

Looking at the code, the first thing I see is the way Employer class approaches the Worker.

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

Instead of accessing a static worker object, you can treat any Worker object independently with this piece of code:

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

Also that is not how we write in C#:

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

The correct way is: public static Foo bar;


About classes and objects:

Your program runs in the scope of static void Main(string[] args) {//stuff happens here} So when a object defined in the boundaries of Main() wants to access another object from the same scope, there is no need to define a second static class.

Now on the other hand, what if there was more classes or scopes? How can we connect them, so they can reliably access one another? Here we have two classes, foo and bar. Foo needs to hand a string variable to bar.

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

Foo and Bar are in two different scopes, so in order to pass myString to myMethod(), we can implement a bridge between them.

static class Bridge 
{
    public static string passThis;
}

In scope 1 ( maybe this was an event that was raised before a bar object was created ) a Foo object gets created. This Foo object passes myString to variable Bridge.passThis .

In scope 2 a Bar object gets created. Bar cannot access the Foo object, so we can't access objectFoo.myString . Instead we access Bridge.passThis and execute myMethod(Bridge.passThis);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM