Search code examples
c#arrayslistpropertiesstatic

C# How do I Create and Reference Multiple Globally Accessible Objects?


My goal is to get and set a single value from a selection of several objects that are accessible from anywhere in the code. For the examples I'm posting I'm only going to show 3 objects, but since there are going to be 10 objects, I want to avoid having to build a 10 tiered switch/if statement every time I try to get or set a value from one of the objects.

I have two classes:

public class TestClassProperties

{
    public static class Foo1
    {
        public static int TestInt { get; set; } = 1;
        public static string TestString { get; set; } = "Hello";
    }

    public static class Foo2
    {
        public static int TestInt { get; set; } = 2;
        public static string TestString { get; set; } = "Hi";
    }

    public static class Foo3
    {
        public static int TestInt { get; set; } = 3;
        public static string TestString { get; set; } = "Hey";
    }
}
public class CallTestClass
{
    string bar;
    void PressKey(int numberPressed)
    {
        if (numberPressed == 1)
        {
            bar = Foo1.TestString;
            Foo1.TestString = "Goodbye";
        }
        else if (numberPressed == 2)
        {
            bar = Foo2.TestString;
            Foo2.TestString = "Goodbye";
        }
        else if (numberPressed == 3)
        {
            bar = Foo3.TestString;
            Foo3.TestString = "Goodbye";
        }
        else
        {
            bar = "Nothing.";
        }
        Console.WriteLine("You said " + bar);
    }
}

There will always be exactly 10 Foo objects. I'm guessing I need a List or an array, but I can't figure out the syntax or methodology since it's multiple objects with multiple properties. There should be a way for me to take the number that was pressed, number 1 for example, and then get the Foo1 string and then set it without the switch/if statement block.

Any help is appreciated.


Solution

  • Just based on the code you're showing, you could satisfy the design goal of maintaining a collection of "objects that are accessible from anywhere in the code" by creating a static collection (in this case I chose a dictionary where the key is an int). To choose "Foo 3" (for example) from anywhere in the app, use the syntax:

    CallTestClass.Foos[3].

    In the code you posted, there doesn't seem to be a need for 10 different Foo classes, and no need tor Foo to be a static class or have static members. You likely could just have 10 instances of the same class...

    public class Foo
    {
        public int TestInt { get; set; }
        public string TestString { get; set; } = string.Empty;
    }
    

    ... initialized to different values.

    public class CallTestClass
    {
        public static Dictionary<int, Foo> Foos = new Dictionary<int, Foo>()
        {
            { 1, new Foo{ TestInt = 1, TestString = "Hello" } },
            { 2, new Foo{ TestInt = 2, TestString = "Hi" } },
            { 3, new Foo{ TestInt = 3, TestString = "Hey" } },
        };
        public static void PressKey(int numberPressed)
        {
            string bar;
            if(Foos.TryGetValue(numberPressed, out Foo foo))
            {
                bar = foo.TestString;
                foo.TestString = "Goodbye";
            }
            else
            {
                bar = "Nothing.";
            }
            Console.WriteLine($"{numberPressed} - You said {bar}.");
        }
    }
    

    Console
    using static CallTestClass;
    
    Console.WriteLine("Enter 1 - 3. To quit press Q");
    
    bool run = true;
    while (run)
    {
        var key = Console.ReadKey(true).Key;
        if (key >= ConsoleKey.D0 && key <= ConsoleKey.D9)
        {
            PressKey(key - ConsoleKey.D0);
        }
        else if (key.Equals(ConsoleKey.Q)) run = false;
    }
    

    demo


    But what if you really have 10 arbitrarily distinct FooN classes with entirely different properties? In that case the dictionary could be <int, object> and would require some kind of switch to resolve the type at runtime. Many ways to do that here's one.

    public class CallTestClass
    {
        public static Dictionary<int, object> Foos = new Dictionary<int, object>()
        {
            { 1, new Foo1{ TestInt = 1, TestString = "Hello" } },
            { 2, new Foo2{ TestInt = 2, TestString = "Hi" } },
            { 3, new Foo3{ TestInt = 3, TestString = "Hey" } },
        };
        public static void PressKey(int numberPressed)
        {
            string bar = "Nothing.";
            if(Foos.TryGetValue(numberPressed, out var foo))
            {
                if (foo is Foo1 foo1) { bar = foo1.TestString; foo1.TestString = "Goodbye"; }
                else if (foo is Foo2 foo2) { bar = foo2.TestString; foo2.TestString = "Goodbye"; }
                else if (foo is Foo3 foo3) { bar = foo3.TestString; foo3.TestString = "Goodbye"; }
            }
            Console.WriteLine($"{numberPressed} - You said {bar}.");
        }
    }