C# Как создать и ссылаться на несколько глобально доступных объектов?

Моя цель — получить и установить одно значение из набора нескольких объектов, доступных из любого места кода. В примерах, которые я публикую, я собираюсь показать только 3 объекта, но, поскольку их будет 10, я хочу избежать необходимости создавать 10-уровневый оператор switch/if каждый раз, когда я пытаюсь получить или установить значение одного из объектов.

У меня есть два класса:

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

Всегда будет ровно 10 объектов Foo. Я предполагаю, что мне нужен список или массив, но я не могу понять синтаксис или методологию, поскольку это несколько объектов с несколькими свойствами. У меня должен быть способ взять нажатое число, например номер 1, а затем получить строку Foo1 и затем установить ее без блока операторов switch/if.

Любая помощь приветствуется.

Лучше было бы знать исходную задачу, а не пытаться решить ее таким странным способом.

rotabor 14.03.2024 22:42

В вашем примере все три класса имеют одинаковые свойства. Будет ли это верно для вашего готового решения или они будут другими? Если они различаются, могут ли классы N наследоваться от базового класса или реализовывать общий интерфейс? Есть ли какой-нибудь логический способ ссылаться на ваши объекты (скажем, индекс или имя)? В первом случае сбор их в массив может иметь смысл. В последнем случае словарь

Flydog57 14.03.2024 22:44

Все классы будут иметь одинаковые свойства в готовом решении. Я экспериментировал со списками и массивами, но не смог найти правильный синтаксис.

Xebarsis 14.03.2024 23:12

Если у них одинаковые свойства, почему у вас разные классы? Разве вы не можете просто создать один класс и иметь несколько экземпляров?

Etienne de Martel 15.03.2024 03:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Просто основываясь на коде, который вы показываете, вы можете достичь цели дизайна по поддержанию коллекции «объектов, доступных из любого места кода», создав статическую коллекцию (в данном случае я выбрал словарь, где ключом является int). Чтобы выбрать «Foo 3» (например) из любого места приложения, используйте синтаксис:

CallTestClass.Foos[3].

В опубликованном вами коде, похоже, нет необходимости в 10 различных Foo классах, а также нет необходимости Foo быть статическим классом или иметь статические члены. Вероятно, у вас может быть всего 10 экземпляров одного и того же класса...

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

... инициализируется разными значениями.

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}.");
    }
}

Консоль
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;
}


Но что, если у вас действительно есть 10 произвольно различных FooN классов с совершенно разными свойствами? В этом случае словарь может быть <int, object> и потребует какого-то переключателя для разрешения типа во время выполнения. Много способов сделать это, вот один.

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}.");
    }
}

Другие вопросы по теме