2008-11-24 21 views
10

To wymyślony przykład, ale powiedzmy, że mam zadeklarowane obiekty:Programowo przy użyciu ciągu jako nazwa obiektu przy uruchamianiu obiektu

CustomObj fooObj; 
CustomObj barObj; 
CustomObj bazObj; 

I mam tablicę ciągów:

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

Jak mogę programowo uzyskać dostęp do obiektów i utworzyć ich instancję za pomocą tablicy łańcuchów, iterując przy użyciu czegoś takiego jak foreach:

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

Mam nadzieję, że pomysł, który próbuję przezwyciężyć, jest jasny. Czy to możliwe w języku C#?

Z góry dziękuję.

+0

Może szukasz przypisanie obiektów do zmiennych instancji w czasie wykonywania lub po prostu utworzyć obiekty dynamicznie? –

Odpowiedz

31

Musisz mieć jasność co do różnicy między obiektem a zmienną. Same obiekty nie mają nazw. Nazwy zmiennych są ustalane podczas kompilacji. Nie można uzyskać dostępu do zmiennych za pomocą nazwy określonej w czasie wykonania, z wyjątkiem odbicia.

Brzmi jak naprawdę prostu chcesz Dictionary<string, CustomObj>:

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

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

Następnie można uzyskać dostęp do obiektów za pomocą podziałowe do słownika.

Jeśli naprawdę chcesz ustawić wartości zmiennych na podstawie ich nazwy w czasie wykonywania, będziesz musiał użyć odbicia (zobacz Type.GetField). Zauważ, że to nie zadziała dla zmiennych lokalnych.

+4

Myślę, że ta odpowiedź powinna przynieść nagrodę "Intuiting What the Customer REALY Wanted". Dobra odpowiedź – ScottTx

+0

A co, jeśli "CustomObj" nie ma konstruktora? – Jnr

+0

@Jnr: To pytanie nie ma zastosowania, biorąc pod uwagę, że OP znajduje się w sytuacji, w której * jest * konstruktorem. Zasadniczo "sposób tworzenia instancji" i "jak śledzić instancje w kolekcji" są całkowicie ortogonalne. –

4

Nie możesz.

Można umieścić je w słowniku:

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

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

Ale to jest tak dobre, jak to się robi.

przypadku przechowywania obiektów w polach w swojej klasie, podobnie jak to:

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

Następnie można do nich dotrzeć poprzez odbicie. Daj mi znać, jeśli jest to trasa, którą chcesz wziąć.

0

Jest to możliwe przy użyciu refleksji, jeśli zmienne są zmiennymi należącymi do klasy, ale są obrzydliwie powolne dla niczego więcej niż bardzo specjalistyczne aplikacje. Myślę, że jeśli szczegółowo opisujesz, co chcesz zrobić, możemy lepiej zaproponować sugestie. Bardzo rzadko zdarza się, że powinieneś uzyskać dostęp do zmiennej takiej, jak robisz.

0

Jedną z opcji jest całkowicie dynamiczna trasa, jak na this article, gdzie można określić blok kodu w ciągu znaków, a następnie kompilacji/uruchomienia go z poziomu programu

0

Inna opcja, mniej elastyczne, ale prościej jest poprzez Activator.CreateInstance - w przypadku pytania o utworzenie nowego obiektu - nie będzie on przypisywał zmiennych dynamicznych, ale czy jest to potrzebne?

2

można użyć funkcji znajdują się:

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

a następnie dostaniesz sterowania, oparty na indeksie jak ten: TextBox firstname = (TextBox) FindControl (string.Concat ("TextBox" indeksu .ToString()), to); Mam nadzieję, że to pomoże.

+0

ID nie jest własnością Control. Możesz użyć właściwości Name: "if (container.Name == controlId)" – Jan

0

@jotte: Wielkie dzięki dla tej funkcji. Użyłem go i działa! Tyle tylko, że trzeba zmienić container.ID przez container.Name

Wtedy po prostu trzeba użyć coś jak (w tym przykładzie jest do wyboru, ale każdy typ zmiennej może działać):

ciąg test = „cbACn "+ i.ToString(); CheckBox cbTest = (CheckBox) FindControl (Test, gbACSCAT); if (cbTest! = Null) { cbTest.Checked = true; }

2

użycie this.Controls.Find (control_name, true) [0] ... po prostu pamiętać, aby rzucić mu

Powiązane problemy