language - object oriented concepts c#
Usar de forma programática una cadena como nombre de objeto al crear una instancia de un objeto (8)
Este es un ejemplo artificial, pero digamos que he declarado objetos:
CustomObj fooObj;
CustomObj barObj;
CustomObj bazObj;
Y tengo una matriz de cadenas:
string[] stringarray = new string[] {"foo","bar","baz"};
¿Cómo puedo acceder programáticamente y crear instancias de esos objetos utilizando la matriz de cadenas, iterando usando algo así como un foreach?
foreach (string i in stringarray) {
`i`Obj = new CustomObj(i);
}
Espero que la idea que trato de transmitir sea clara. ¿Es esto posible en C #?
Gracias por adelantado.
Debe tener clara su mente acerca de la diferencia entre un objeto y una variable. Los objetos en sí mismos no tienen nombres. Los nombres de las variables se deciden en tiempo de compilación. No puede acceder a las variables mediante un nombre determinado en el tiempo de ejecución, excepto a través de la reflexión.
Parece que realmente solo quieres un Dictionary<string, CustomObj>
:
Dictionary<string, CustomObj> map = new Dictionary<string, CustomObj>();
foreach (string name in stringArray)
{
map[name] = new CustomObj(name);
}
Luego puede acceder a los objetos usando el indexador al diccionario.
Si realmente está tratando de establecer los valores de las variables en función de su nombre en el momento de la ejecución, tendrá que usar la reflexión (vea Type.GetField ). Tenga en cuenta que esto no funcionará para las variables locales.
Esto es posible utilizando la reflexión si las variables son variables miembro de la clase, pero es terriblemente lento para algo más que aplicaciones muy especializadas. Creo que si detallas lo que intentas hacer, podemos ofrecer mejores sugerencias. Es muy raro que haya un caso en el que deba acceder a una variable como lo hace.
No puedes.
Puede colocarlos en un diccionario:
Dictionary<String, CustomObj> objs = new Dictionary<String, CustomObj>();
foreach (string i in stringarray)
{
objs[i] = new CustomObj(i);
}
Pero eso es todo lo bueno que se puede.
Si almacena los objetos en los campos de su clase, así:
public class SomeClass
{
private CustomObj fooObj;
private CustomObj barObj;
private CustomObj bazObj;
}
Entonces puedes alcanzarlos a través de la reflexión. Avíseme si esa es la ruta que desea tomar.
Otra opción, menos flexible, pero más simple es a través de Activator.CreateInstance , donde se solicita la creación de un nuevo objeto; no se asignará a las variables dinámicas, pero ¿es necesario?
Una opción es la ruta totalmente dinámica, según este artículo , donde especifica un bloque de código en una cadena y luego compila / ejecuta desde dentro de su programa
puedes usar una función de búsqueda:
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;
}
y luego obtendrá su control, basado en un índice como este: TextBox firstname = (TextBox) FindControl (string.Concat ("TextBox", index.ToString ()), this); Espero que esto ayude.
@jotte: Muchas gracias por esa función. ¡Lo usé y funciona! Excepto que necesita cambiar el contenedor. ID por contenedor.Nombre
Entonces solo necesitas usar algo como (este ejemplo es para casilla de verificación, pero cualquier tipo de variable podría funcionar):
cadena Test = "cbACn" + i.ToString (); CheckBox cbTest = (CheckBox) FindControl (Test, gbACSCAT); if (cbTest! = null) {cbTest.Checked = true; }
usa this.Controls.Find (control_name, true) [0] ... solo recuerda lanzarlo