Программно использовать строку как имя объекта при создании объекта

Это надуманный пример, но позволяет сказать, что я объявил объекты:

CustomObj fooObj;
CustomObj barObj;
CustomObj bazObj;

И у меня есть строковый массив:

string[] stringarray = new string[] {"foo","bar","baz"};

Как я могу программно получить доступ к этим объектам и создать их с помощью массива строк, итерации с использованием чего-то вроде foreach:

foreach (string i in stringarray) {
    `i`Obj = new CustomObj(i);
}

Надеюсь, что идея, которую я пытаюсь понять, понятна. Возможно ли это в С#?

Спасибо заранее.

Ответ 1

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

Похоже, вы просто хотите Dictionary<string, CustomObj>:

Dictionary<string, CustomObj> map = new Dictionary<string, CustomObj>();

foreach (string name in stringArray)
{
    map[name] = new CustomObj(name);
}

Затем вы можете получить доступ к объектам с помощью индексатора в словаре.

Если вы действительно пытаетесь установить значения переменных на основе их имени во время выполнения, вам придется использовать отражение (см. Type.GetField). Обратите внимание, что это не будет работать для локальных переменных.

Ответ 2

Вы не можете.

Вы можете поместить их в словарь:

Dictionary<String, CustomObj> objs = new Dictionary<String, CustomObj>();

foreach (string i in stringarray)
{
    objs[i] = new CustomObj(i);
}

Но это примерно так же хорошо, как и получается.

Если вы храните объекты в полях своего класса, например:

public class SomeClass
{
    private CustomObj fooObj;
    private CustomObj barObj;
    private CustomObj bazObj;
}

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

Ответ 3

вы можете использовать функцию поиска:

    public static Control FindControl(string controlId, Control container)
    {
        if (container.ID == controlId)
            return container;

        foreach (Control control in container.Controls)
        {
            Control c = FindControl(controlId, control);
            if (c != null)
                return c;
        }
        return null;
    }

а затем вы получите свой контроль на основе индекса следующим образом: TextBox firstname = (TextBox) FindControl (string.Concat( "TextBox", index.ToString()), это); Надеюсь, это поможет.

Ответ 4

используйте this.Controls.Find(control_name, true) [0]... просто запомните его

Ответ 5

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

Ответ 6

Один из вариантов - это полностью динамический маршрут, согласно в этой статье, где вы указываете блок кода в строке, а затем компилируете/выполняете это из вашей программы

Ответ 7

Другой вариант, менее гибкий, но более простой - через Activator.CreateInstance - где вы просите создать новый объект - он выиграл 't назначать динамические переменные, но это необходимо?

Ответ 8

@jotte: Большое спасибо за эту функцию. Я использовал его, и он работает! За исключением того, что вам нужно изменить container.ID по контейнеру. Имя

Тогда вам просто нужно использовать что-то вроде этого (этот пример для флажка, но любой тип переменной мог бы работать):

string Test = "cbACn" + i.ToString(); CheckBox cbTest = (CheckBox) FindControl (Test, gbACSCAT); if (cbTest!= null) {   cbTest.Checked = true; }