Hacer un casting a partir del type

18/05/2007 - 17:46 por ANT1 | Informe spam
Hola tengo en un string el nombre de la clase de un objeto y necesito
hacer un casting a partir de este.

¿Como se puede hacer?

Gracias, un saludo.

Preguntas similare

Leer las respuestas

#6 Hernan
21/05/2007 - 11:22 | Informe spam
La verdad es que ahora que me lo plantean de esta manera no se me
habia ocurrido verlo asi. Y tienen la razon. Les voy a plantear un
poco mas mi aplicacion a ver si me apueden ayudar.

Lo que estoy intentando es crear mi propio backup unas colecciones de
objetos de diferentes clases (Cliente, Empresa, ...). De momento lo
que hice fue crear un archivo de texto (ahora mismo lo estoy
orientando a xml), en el que almaceno la clase del objeto (de ahi el
string del que queria sacar la clase del objeto) y un string con el
objeto serializado y convertido a base64string.

Mi intencion era despues a partir de la clase y de la cadena-backup
del objeto recuperar dicho objeto.



Antes de contestarte, te haré una pregunta:
¿Por qué necesitas complicar tanto el código?

C# NO es un lenguaje dinámico. La "dinamicidad de tipos" que provee la
Reflexion es para un caso MUY concreto: cuando el tipo del objeto es
desconocido al momento de compilar tu aplicación.

¡Para todo lo demás usa un switch!

Todas mias clases heredan de una clase base ObjetoBase. ¿Se podria
hacer algo como lo siguiente?

string clase = "Clase_del_objeto";
string valorObjeto = "Base64String_almacenado_enbackup";
ObjetoBase objetoNuevo > (clase)ObjetoBase.MetodoReconversor(valorObjeto);

¿"ObjetoNuevo" tendria la propiedades de la clase del backup, aunque
la clase ObjetoBase no las tenga definidas?



Eso no es C#.

Pero puedes hacer algo así:

string claseObj = "Clase_del_objeto";
string valorObjeto = "Base64String_almacenado_enbackup";
ObjetoBase objetoNuevo ObjetoBase.MetodoReconversor(claseObj, valorObjeto);

MetodoReconversor devolvería una instancia de tipo claseObj concreta.
Puedes para objetoNuevo a cualquier atributo o método que espere
una instancia de tipo claseObj.

MetodoReconversor usa el bendito switch:

ObjetoBase miObj = null;
switch (claseObj) {
case "Empresa": miObj = new Empresa(); break;
case "Cliente": miObj = new Cliente(); break;
}
// luego lleno miObj con valorObjeto
// ...
return miObj;

Si estás usando la serialización de .NET entonces ni siquiera
necesitas ni el string del tipo. El tipo de dato esta incluído
dentro la serialización (es parte de valorObjeto)
Respuesta Responder a este mensaje
#7 Alberto Poblacion
21/05/2007 - 11:38 | Informe spam
"ANT1" wrote in message
news:
Lo que estoy intentando es crear mi propio backup unas colecciones de
objetos de diferentes clases (Cliente, Empresa, ...). De momento lo
que hice fue crear un archivo de texto (ahora mismo lo estoy
orientando a xml), en el que almaceno la clase del objeto (de ahi el
string del que queria sacar la clase del objeto) y un string con el
objeto serializado y convertido a base64string.

Mi intencion era despues a partir de la clase y de la cadena-backup
del objeto recuperar dicho objeto.



Y digo yo, ¿por qué no usas la serialización de .Net, que ya hace todo
esto directamente? Puedes usar el BinaryFormatter o el SoapFormatter, que ya
te envían al archivo la clase del objeto y el contenido serializado, y al
deserializarlo te devuelven el objeto correcto con todo su contenido.


Todas mias clases heredan de una clase base ObjetoBase. ¿Se podria
hacer algo como lo siguiente?



Podrías poner algo así en la clase base:

[Serializable] class ObjetoBase
{
public void Sálvate(Stream s)
{
SopaFormatter sf = new SoapFormatter();
sf.Serialize(s, this);
}
public static ObjetoBase RecuperaObjeto(Stream s)
{
SopaFormatter sf = new SoapFormatter();
return (ObjetoBase) sf.Deserialize(s);
}
//...Resto de la clase
}

Aunque al recuperar los datos el objeto devuelto es de tipo ObjetoBase,
dentro contiene la clase hija que realmente salvaste, con lo que le puedes
hacer un cast al tipo de la clase hija.

Cliente RecuperarCliente(Stream s)
{
return (Cliente)Cliente.RecuperaObjeto(s);
}
Respuesta Responder a este mensaje
#8 ANT1
21/05/2007 - 12:23 | Informe spam
Antes de contestarte, te haré una pregunta:
¿Por qué necesitas complicar tanto el código?



La verdad es que no es mi intencion complicar el codigo, todo lo
contrario trato de hacerlo lo mas sencillo posible. Lo malo es que no
se como hacerlo y esta es la manera que mejor se me ha ocurrido. Como
ves es una idea de lo que me gustaria hacer que aun no tengo muy
clara, por eso preguntaba a ver si alguien podia ayudarme a
orientarme.

Eso no es C#.

Pero puedes hacer algo así:

string claseObj = "Clase_del_objeto";
string valorObjeto = "Base64String_almacenado_enbackup";
ObjetoBase objetoNuevo > ObjetoBase.MetodoReconversor(claseObj, valorObjeto);

MetodoReconversor devolvería una instancia de tipo claseObj concreta.
Puedes para objetoNuevo a cualquier atributo o método que espere
una instancia de tipo claseObj.



La verdad es que ese codigo lo escribi a toda velocidad. Pero mas o
menos intentaba poner lo que tu comentas.


MetodoReconversor usa el bendito switch:

ObjetoBase miObj = null;
switch (claseObj) {
case "Empresa": miObj = new Empresa(); break;
case "Cliente": miObj = new Cliente(); break;
}
// luego lleno miObj con valorObjeto
// ...
return miObj;



El metodo switch ni se me habia ocurrido. Hay veces que me complico
cuando con las cosas mas sencillas se podria hacer.

Si estás usando la serialización de .NET entonces ni siquiera
necesitas ni el string del tipo. El tipo de dato esta incluído
dentro la serialización (es parte de valorObjeto)



Esta ultima parte me interesa especialmente, y es que es la duda que
tengo. ¿Aunque recupere los datos de un objeto que era de la clase
Cliente, por ejemplo, a un objeto base suyo, ObjetoBase, esta nueva
instancia contendria los valores del cliente original? aunque no
pudiese acceder a ellos ya que ObjetoBase no tiene definidas dichas
propiedades y metodos. Ya que sabiendo esto y haciendo y
posteriormente el switch estaria todo.

Aunque si no tengo el string con la clase del objeto, ¿como podria
saberla para hacer el witch?

Un saludo
Respuesta Responder a este mensaje
#9 ANT1
21/05/2007 - 12:46 | Informe spam
Hola Alberto.

Ya uso la serializacion. Mi clase ObjetoBase es serializable y
actualmente tengo estos dos metodos definidos en ella para crear y
restaurar el backup.

public string CREATEBACKUP()
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, this);
return Convert.ToBase64String(ms.ToArray());
//ms.Close();
}

protected static object RESTOREBACKUP(string tuitui)
{
MemoryStream ms = new
MemoryStream(Convert.FromBase64String(tuitui));
BinaryFormatter bf = new BinaryFormatter();
return bf.Deserialize(ms);
}

Los strings retornados y enviados a los metodos seria lo que
almacenaria en mi archivo de texto a modo de backup.

RestoreBackup es protected pq tenia intencion de una vez sabiendo que
clase de objeto es llamar a metodo estatico de esta que se encargaria
de hacer el casting y el save a la BD. Pero el ponerlos como publico y
con el switch que me comenta Hernan me parece una buena idea.

El caso es que cuando me decis que al ser serializado que se puede
obtener toda la informacion del objeto que se almaceno, como su clase,
yo es que no se como se haria.
Respuesta Responder a este mensaje
#10 Hernan
21/05/2007 - 14:06 | Informe spam
protected static object RESTOREBACKUP(string tuitui)
{
MemoryStream ms = new
MemoryStream(Convert.FromBase64String(tuitui));
BinaryFormatter bf = new BinaryFormatter();
return bf.Deserialize(ms);
}

Los strings retornados y enviados a los metodos seria lo que
almacenaria en mi archivo de texto a modo de backup.

RestoreBackup es protected pq tenia intencion de una vez sabiendo que
clase de objeto es llamar a metodo estatico de esta que se encargaria
de hacer el casting y el save a la BD. Pero el ponerlos como publico y
con el switch que me comenta Hernan me parece una buena idea.

El caso es que cuando me decis que al ser serializado que se puede
obtener toda la informacion del objeto que se almaceno, como su clase,
yo es que no se como se haria.



Pero en este caso no necesitas nada. No hace falta hacer un switch
ni nada por el estilo. bf.Deserialize(ms) ya te devuelve el objeto
con el tipo correspondiente (Empresa, Cliente, etc.)
Si todos los objetos que deserializas son de la jerarquía de clase
que has mencionado incluso podrías hacer que RESTOREBACKUP devuelva
un tipo ObjetoBase como ya te ha dicho Alberto.

Los cast (usando ifs o switch) solo los necesitas si luego tienes
que cambiar el flujo de tu programa en base al tipo real del
objeto. El switch o if lo puedes hacer mediante GetType()
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida