Vraag Het programmeren van een string als objectnaam bij het instantiëren van een object


Dit is een gekunsteld voorbeeld, maar laten we zeggen dat ik voorwerpen heb verklaard:

CustomObj fooObj;
CustomObj barObj;
CustomObj bazObj;

En ik heb een string array:

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

Hoe kan ik die objecten programmatisch benaderen en instantiëren met behulp van de reeksreeksen, itereren met iets als een foreach:

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

Ik hoop dat het idee dat ik probeer over te brengen duidelijk is. Is dit mogelijk in C #?

Bij voorbaat bedankt.


10
2017-11-24 12:16


oorsprong


antwoorden:


U moet helder zijn in uw gedachten over het verschil tussen een object en een variabele. Objecten zelf hebben geen namen. Variabele namen worden beslist tijdens het compileren. U hebt geen toegang tot variabelen via een door de uitvoeringstijd bepaalde naam behalve via reflectie.

Het klinkt als jij werkelijk wil gewoon een Dictionary<string, CustomObj>:

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

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

U kunt dan toegang krijgen tot de objecten met behulp van de indexeerfunctie voor het woordenboek.

Als u echt probeert de waarden van variabelen in te stellen op basis van hun naam tijdens de uitvoering, moet u reflectie gebruiken (zie Type.GetField). Merk op dat dit niet zal werken voor lokale variabelen.


31
2017-11-24 12:19



Dat kan niet.

U kunt ze in een woordenboek plaatsen:

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

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

Maar dat is ongeveer zo goed als het wordt.

Als u de objecten opslaat in velden in uw klas, zoals deze:

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

Dan kun je ze bereiken door te reflecteren. Laat me weten of dat de route is die je wilt nemen.


4
2017-11-24 12:19



je kunt een zoekfunctie gebruiken:

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

en dan krijg je je controle, op basis van index als deze: TextBox firstname = (TextBox) FindControl (string.Concat ("TextBox", index.ToString ()), this); Ik hoop dat dit helpt.


2
2018-06-19 18:36



gebruik this.Controls.Find (control_name, true) [0] ... vergeet alleen niet om het te casten


2
2018-02-21 09:52



Dit is mogelijk met behulp van reflectie als de variabelen variabelen van een klasse lid zijn, maar het is afschuwelijk langzaam voor iets meer dan zeer gespecialiseerde toepassingen. Ik denk dat als je detailleert wat je probeert te doen, we suggesties beter kunnen aanbieden. Er is zeer zelden een geval waarin je toegang zou moeten hebben tot een variabele zoals je doet.


0
2017-11-24 12:21



Een optie is de volledig dynamische route, zoals per Dit artikel, waar u een codeblok in een tekenreeks opgeeft en vervolgens compileert / uitvoert vanuit uw programma


0
2017-11-24 12:21



Een andere optie, minder flexibel, maar eenvoudiger is via Activator.CreateInstance - waar u vraagt ​​om een ​​nieuw object te maken - het zal niet toewijzen aan dynamische variabelen, maar is dat nodig?


0
2017-11-24 12:23



@jotte: Heel erg bedankt voor die functie. Ik heb het gebruikt en het werkt! Behalve dat je container.ID moet veranderen door container.Name

Dan moet je gewoon zoiets gebruiken (dit voorbeeld is voor checkbox, maar elk type variabele zou kunnen werken):

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


0
2018-04-09 19:11