Foros del Web » Programación para mayores de 30 ;) » .NET »

Crear una clase dinámicamente

Estas en el tema de Crear una clase dinámicamente en el foro de .NET en Foros del Web. Hola chicos. Ya pregunté hace unas semanas cómo crear enumerados dinámicos, pero bueno, no tuve demasiado éxito. Doy un paso más: me gustaría crear una ...
  #1 (permalink)  
Antiguo 09/07/2014, 07:53
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Crear una clase dinámicamente

Hola chicos. Ya pregunté hace unas semanas cómo crear enumerados dinámicos, pero bueno, no tuve demasiado éxito. Doy un paso más: me gustaría crear una clase dinámicamente.

La idea es tener una clase (llamémosla Nombres), que instancie constantes de tipo int cuyos nombres se lean de un xml.

Ejemplo de código que debo generar:


Código:
Public class Nombres{

public const int nombreA = 0;
public const int nombreB = 1;
...

}
Es necesario generar la clase de manera dinámica, algo así como lo que hacen los compiladores. ¿Alguna idea? Gracias
  #2 (permalink)  
Antiguo 09/07/2014, 07:55
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Yo alguna vez he tenido que hacer algo así y la solución es usar un Dictionary donde la "key" sea el nombre de la variable del xml y el "value" el contenido.
__________________
Aviso: No se resuelven dudas por MP!
  #3 (permalink)  
Antiguo 09/07/2014, 08:03
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Cita:
Iniciado por Malenko Ver Mensaje
Yo alguna vez he tenido que hacer algo así y la solución es usar un Dictionary donde la "key" sea el nombre de la variable del xml y el "value" el contenido.
Diría que no me sirve. Necesito acceder a estas constantes tal que así:

Nombres.NombreA

Para poder hacer comparaciones del estilo:

if(EventoEntrada==Nombres.NombreA){...}

Donde EventoEntrada es otro int.

En mi aplicación hay múltiples comparaciones. Si utilizo un diccionario debería comparar strings y NO puedo hacer esto.

Gracias
  #4 (permalink)  
Antiguo 09/07/2014, 08:06
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Los diccionarios porque han de ser de Strings únicamente? Para eso estan los genericos ;)
__________________
Aviso: No se resuelven dudas por MP!
  #5 (permalink)  
Antiguo 09/07/2014, 08:08
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Cita:
Iniciado por Malenko Ver Mensaje
Los diccionarios porque han de ser de Strings únicamente? Para eso estan los genericos ;)
Podrías poner un ejemplo de lo que dices? Aunque sea chorra.

Es que no se me ocurre la manera de hacerlo con un diccionario.

De qué tipo tendría que ser el Key?
  #6 (permalink)  
Antiguo 09/07/2014, 08:12
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Lo mejor es que mires la documentación de MSDN para luego ver algún ejemplo sencillo.
__________________
Aviso: No se resuelven dudas por MP!
  #7 (permalink)  
Antiguo 09/07/2014, 08:19
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

A priori diría que sé utilizar un diccionario pero mi duda al respecto es la siguiente.

Si yo tengo un diccionario del tipo Dictionary<string, int>

Para sacar el valor de una instancia concreta del diccionario tendré que hacer
int value = Dictionary["string"]

Lo cual, internamente hace una búsqueda hasta que se hace matching con el key que toca y devuelve el valor de ese key. Es decir, internamente se comparan strings, cosa que debo evitar a toda costa. ¿Me equivoco en algo?

Agradezco tu ayuda, compañero ;)
  #8 (permalink)  
Antiguo 09/07/2014, 08:46
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

En realidad lo que hace es usar el método GetHashCode del tipo de dato que se TKey, en este caso usará la función de hashing de .net para las cadenas. Al usar un diccionario, el coste de acceso al elemento es el coste de calcular la función de hash más el de un acceso directo O(1). Lo que tu dices de ir comparando string por string sería si usases una lista para almacenar, en tal caso si que sería un coste O(n)
__________________
Aviso: No se resuelven dudas por MP!
  #9 (permalink)  
Antiguo 09/07/2014, 08:50
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Cita:
Iniciado por Malenko Ver Mensaje
En realidad lo que hace es usar el método GetHashCode del tipo de dato que se TKey, en este caso usará la función de hashing de .net para las cadenas. Al usar un diccionario, el coste de acceso al elemento es el coste de calcular la función de hash más el de un acceso directo O(1). Lo que tu dices de ir comparando string por string sería si usases una lista para almacenar, en tal caso si que sería un coste O(n)
Acabáramos! Entonces el acceso al value tal y como lo he puesto tiene un coste (prácticamente) constante?

Si esto es así sí que me sirve, muchas gracias
  #10 (permalink)  
Antiguo 09/07/2014, 09:01
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Sí, exacto. En las clases nativas el coste es prácticamente constante, y en las propias depende de la implementación que hagas del GetHashCode, pero sí, el acceso a TValue es constante. Como te dije antes, yo ya me encontré con este problema y tras muchas vueltas la mejor solución es usar un diccionario. Es más, un último apunte. Si defines el diccionario como <string, string> solo podrás almacenar strings y lo haces como <string, int> solo podrás almacenar int. Esto no te interesará si tienes variables de ambos tipos. En tal caso mi sugerencia es usar <string, Object> para almacenar objetos de forma genérica :D
__________________
Aviso: No se resuelven dudas por MP!
  #11 (permalink)  
Antiguo 09/07/2014, 09:07
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Muchas gracias, crack. Así da gusto.
  #12 (permalink)  
Antiguo 09/07/2014, 13:07
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Ups! Se me ha ido la pinza a base de bien.

Vamos a ver, la búsqueda está claro que es constante (no sé en qué estaba pensando).

Lo que me interesa saber es si internamente se hace un stringCompare cuando se ejecuta la instrucción NombreDiccionario["NombreA"]

Asumo que es una comparación de strings lo que se realiza, verdad? De ser así, sigue sin valerme!
  #13 (permalink)  
Antiguo 09/07/2014, 13:13
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Porque no? Puedes poner algun ejemplo de lo que quieres hacer para ver si es viable?
__________________
Aviso: No se resuelven dudas por MP!
  #14 (permalink)  
Antiguo 09/07/2014, 17:53
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

A ver si consigo explicarme.

Necesito comparar números contra números (con nombre).

Por ahora tengo una clase Tags tal que así:

Código:
Public class Tags{

public const int NombreDeEvento1 = 0;
public const int NombreDeEvento2 = 1;
...
}
De forma que cuando comparo en mi programa siempre hago algo así como:
if(NúmeroDeEvento == Tags.NombreDeEventoN)

Donde númeroDeEvento es un int y Tags.NombreDeEventoN es el nombre del evento enésimo definido en la clase Tags. Claro, de esta forma, tengo que definirme a mano los tags si añado algún evento nuevo y quisiera que esto fuera automático.

Si lo hago con Diccionarios, tendría algo así:

Código:
Dictionary<string, int> dic = new Dictionary<string, int>();
dic.Add("NombreDeEvento1", 0);
int valor = dic["NombreDeEvento1"]
...
Cuando recojo el valor para ese KEY ("NombreDeEvento1") internamente la librería CREO que hace un stringCompare para extraer el valor. Y digo creo porque no lo sé seguro (lo que yo sobreentiendo es que el acceso es constante pero la comparación de strings no me la quita nadie).

Me gustaría sabe realmente qué leches hace internamente el Dictionary: si yo realmente le paso una cadena pero compara números, perfecto. AHORA, si hay algún StringCompare interno, no me vale porque resultaría muy ineficiente si en cada ciclo de programa comparo un porrón de strings.

No sé si se entiende el matiz


Gracias :)
  #15 (permalink)  
Antiguo 10/07/2014, 00:58
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Este código que has puesto:

Código:
if(NúmeroDeEvento == Tags.NombreDeEventoN)
quedaría traducido a:

Código:
if (NúmeroDeEvento == dict["NombreDeEventoN"])
Si lo que quieres saber es como funciona, es facil. Primero llama a la función de hashing de los string para obtener el valor de hash de "NombreDeEventoN", lo que dará un número entero. A continuación se accede dentro de la tabla a la posición que se ha calculado antes y obtenemos el valor almacenado (un int). Y finalmente se hace la comparación booleana entre "NúmeroDeEvento" y el int recuperado.

En ningún momento hay un StringCompare.
__________________
Aviso: No se resuelven dudas por MP!
  #16 (permalink)  
Antiguo 10/07/2014, 01:34
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Si, sabía que la comparación quedaba así. Mi duda es si había un stringCompare. Okay pues, debería servir entonces.

Gracias y disculpa el follón, es que tengo que evitar la implementación comparando strings a toda costa.
  #17 (permalink)  
Antiguo 10/07/2014, 01:39
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Si, creo que ya te comenté antes que aunque trabajas con Strings en ningún momento las comparas, sino que comparas sus códigos de hash. Por curiosidad, porque no quieres usar comparaciones de Strings?
__________________
Aviso: No se resuelven dudas por MP!
  #18 (permalink)  
Antiguo 10/07/2014, 02:10
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Pues la cosa es que un profesor me estaba comentando que entendía que sí había un StringCompare.

Estoy haciendo una API de gestión de Inteligencia Artificial. Entonces claro, tengo que comparar múltiples cosas, eventos, acciones, etc... Mi implementación tiene que ser lo más fluida posible, no puedo permitirme el lujo de comparar miles de strings entre sí en cada ciclo de programa, lo convierto todo a tokens y compruebo únicamente números :)
  #19 (permalink)  
Antiguo 10/07/2014, 02:21
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Pero hay que vigilar con las optimizaciones. El código no solo ha de funcionar bien y rápido, sino que además ha de poder ser mantenible. Por ejemplo, el ejemplo que ponias antes:

Código:
Public class Tags{

public const int NombreDeEvento1 = 0;
public const int NombreDeEvento2 = 1;
...
}
Era mucho mejor usar una enumeración ya que no has de meter una clase ("Tags") de por medio, ni instanciarla ni nada, con la mejora en rendimiento que conlleva:

Código:
Public enum Tags{

NombreDeEvento1 = 0,
NombreDeEvento2 = 1,
...
}
A veces se gana más haciendo una estructura correcta del programa que no evitando cosillas como ese tipo de comparaciones, aunque si, siempre que se pueda se ha de hacer ambas cosas :P
__________________
Aviso: No se resuelven dudas por MP!
  #20 (permalink)  
Antiguo 10/07/2014, 02:34
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Si si, lo sé. Lo de la clase Tags era una solución chapucera que iba a cambiar sí o sí.

Aunque realmente ni siquiera instancio la clase Tags. Son consultas a sus constantes lo que hago, lo cual sigue siendo muy rápido, pero claro, depende de lo que añadas en Tags que funcione el programa o no, y eso no puede ser.
  #21 (permalink)  
Antiguo 10/07/2014, 03:00
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Crear una clase dinámicamente

Cita:
Iniciado por TitoFlecks Ver Mensaje
Si si, lo sé. Lo de la clase Tags era una solución chapucera que iba a cambiar sí o sí.

Aunque realmente ni siquiera instancio la clase Tags. Son consultas a sus constantes lo que hago, lo cual sigue siendo muy rápido, pero claro, depende de lo que añadas en Tags que funcione el programa o no, y eso no puede ser.
En realidad si que la tendrías que instanciar para acceder a sus miembros ;)
__________________
Aviso: No se resuelven dudas por MP!
  #22 (permalink)  
Antiguo 10/07/2014, 08:38
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Yo por instanciar entiendo hacer un new de un objeto de tipo Tags. Y no hago eso en ningún momento.

Simplemente, defino la clase como pública y accedo a las constantes haciendo Tags.NombreDeEvento, siendo NombreDeEvento un public const int. Realmente es como tener un enumerado en la práctica, mi clase Tags no vale para otra cosa jaja

Te haré caso igualmente. Creo que la solución puede ser bastante buena, aunque es fácil que mi tutor sospeche de alguna cadena o algo así :P

Gracias crack
  #23 (permalink)  
Antiguo 10/07/2014, 10:51
 
Fecha de Ingreso: abril-2011
Mensajes: 1.342
Antigüedad: 13 años
Puntos: 344
Respuesta: Crear una clase dinámicamente

Buenas,

Pues me temo que el Dictionary si hace comparación de cadenas. Cualquier estructura basada en tablas hash tiene que comparar el elemento que se busca.

El proceso es tal que así:

1. Con la clave (en tu caso un string) se obtiene el hash (una posición)
2. Si se encuentra un elemento con ese hash, se debe comparar la clave del elemento encontrado con la clave de búsqueda, y si son iguales, se devuelve el elemento. En caso contrario, hay que hacer una búsqueda en el espacio de colisiones.

El espacio de colisiones es el lugar donde están aquellas claves que tiene hash duplicados. Por ejemplo, la cadena "Hola" y "Adios" podrían devolver el mismo hash (según como se calcule), aunque no utilizando la función hash por defecto que implementa .NET para las cadenas. Pero en cualquier caso, la comparación es inevitable.

Para que veas que no miento, esta es la implementación de la búsqueda de la clave en un Dictionary:

Código C#:
Ver original
  1. private int FindEntry(TKey key)
  2. {
  3.     if (key == null)
  4.     {
  5.         ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  6.     }
  7.     if (this.buckets != null)
  8.     {
  9.         int num = this.comparer.GetHashCode(key) & 2147483647;
  10.         for (int i = this.buckets[num % this.buckets.Length]; i >= 0; i = this.entries[i].next)
  11.         {
  12.             if (this.entries[i].hashCode == num && this.comparer.Equals(this.entries[i].key, key))
  13.             {
  14.                 return i;
  15.             }
  16.         }
  17.     }
  18.     return -1;
  19. }

Como verás se hace un equals para comparar el valor de la clave y el encontrado.
Un saludo.
  #24 (permalink)  
Antiguo 11/07/2014, 07:16
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Crear una clase dinámicamente

Pues menuda putada... y chicos, para crear de cero la clase? Aunque esto sea más lento, me lo puedo permitir, lo que no puedo utilizar son comparaciones de strings.

¿Sabéis alguna manera de crear una clase dinámicamente? Dejándonos de estructuras de datos, porque por lo visto todas tiran de Equals y demás.

Etiquetas: clase
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:49.