2009-07-30 14 views
27

Tengo un objeto:¿Cómo se convierte el objeto al tipo descrito por Tipo de clase?

ExampleClass ex = new ExampleClass(); 

Y:

Type TargetType 

me gustaría correr ex con el tipo descrito por TargetType así:

Object o = (TargetType) ex; 

Pero cuando hago esto consiga:

El tipo o nombre del espacio de nombres 't' podría no encontrarse

Entonces, ¿cómo hacer esto? ¿Me estoy perdiendo algo obvio aquí?

Actualización:

me gustaría obtener algo como esto:

public CustomClass MyClassOuter 
{ 
    get 
    { 
     return (CustomClass) otherClass; 
    } 
} 

private otherClass; 

Y porque voy a tener muchas propiedades como esta me gustaría hacer esto:

public CustomClass MyClassOuter 
{ 
    get 
    { 
     return (GetThisPropertyType()) otherClass; 
    } 
} 

private SomeOtherTypeClass otherClass; 

Contexto:

Normalmente, en mi contexto en mi clase, necesito crear muchas propiedades s. Y en cada uno, reemplace el casting por el tipo de propiedad. No parece tener sentido para mí (en mi contexto) porque sé qué tipo de devolución es y me gustaría escribir algún tipo de código que me haga el casting. Tal vez sea el caso de los genéricos, aún no lo sé.

Es como puedo asegurar en esta propiedad que obtengo el objeto correcto y en el tipo correcto y soy 100% capaz de convertirlo al tipo de propiedad.

Todo lo que necesito hacer para no tener que especificar en cada propiedad que tiene que "agregar valor a CustomClass", me gustaría hacer algo así como "valor de conversión a la misma clase que esta propiedad es".

Por ejemplo:

class MYBaseClass 
{ 
    protected List<Object> MyInternalObjects; 
} 

class MyClass 
{ 
    public SpecialClass MyVeryOwnSpecialObject 
    { 
     get 
     { 
      return (SpecialClass) MyInteralObjects["MyVeryOwnSpecialObject"]; 
     } 
    } 
} 

Y bien - Puedo hacer muchas propiedades como ésta anteriormente - pero hay 2 problemas:

1) que necesito para especificar el nombre del objeto en MyInternalObjects pero es lo mismo que el nombre de la propiedad. Esto lo resolví con System.Reflection.MethodBase.GetCurrentMethod(). Name.

2) En cada propiedad, necesito convertir objetos de MyInternalObjects a diferentes tipos. En MyVeryOwnSpecialObject, por ejemplo, a SpecialClass. Siempre es la misma clase que la propiedad.

Por eso me gustaría hacer algo como esto:

class MYBaseClass 
{ 
    protected List<Object> MyInternalObjects; 
} 

class MyClass 
{ 
    public SpecialClass MyVeryOwnSpecialObject 
    { 
     get 
     { 
      return (GetPropertyType()) MyInteralObjects[System.Reflection.MethodBase.GetCurrentMethod().Name]; 
     } 
    } 
} 

Y ahora preocupaciones: Ok, ¿para qué? Porque más adelante en mi aplicación tendré todos los beneficios de los tipos seguros y demás (intellisense).

Segundo: ¿pero ahora perderá la seguridad del tipo en este lugar? No.Porque estoy muy seguro de que tengo un objeto de mi tipo en una lista.

+0

He actualizado mi respuesta para responder a su edición. Sospecho que tendremos que ver un ejemplo * completo * para que esta pregunta tenga sentido. –

+0

"Siempre es la misma clase que la propiedad", así que échalo a ese tipo. Usted conoce ese tipo en tiempo de compilación; ¿Por qué hacer algo más? ¿Solo para ahorrar algo de tipeo? –

+0

Si sale de la caja verá los beneficios de este –

Respuesta

10
Object o = (TargetType) ex; 

Este código es inútil. Puede tener un tipo a la derecha, pero sigue siendo solo un objeto en el lado izquierdo. No puede usar la funcionalidad específica de TargetType como esta.


Así es como se puede invocar un método de un objeto desconocido de un tipo determinado:

object myObject = new UnknownType(); 
Type t = typeof(UnknownType); // myObject.GetType() would also work 
MethodInfo sayHelloMethod = t.GetMethod("SayHello"); 
sayHelloMethod.Invoke(myObject, null); 

Con esta clase UnknownType:

class UnknownType 
{ 
    public void SayHello() 
    { 
     Console.WriteLine("Hello world."); 
    } 
} 
+0

Necesito usar el comando exp para escribir mi 'TargetType' personalizado. ¿Qué propones para hacer esto? –

+0

Tendrá que invocar métodos (o lo que quiera hacer) a través de la reflexión. Trataré de encontrar un ejemplo. – weiqure

+0

He actualizado la pregunta para mostrar el contexto –

0
if (ex is ExampleClass) 
{ 
    ExampleClass myObject = (ExampleClass)ex; 
} 

Eso sería hacerlo pero supongo que la pregunta es ¿qué intentas lograr y por qué? A menudo encuentro que si algo parece realmente, realmente difícil, entonces probablemente lo estoy haciendo mal.

+0

He actualizado la pregunta para mostrar el contexto –

3

Por lo general, el deseo de hacer esto indica un malentendido. Sin embargo, hay son muy ocasionalmente razones legítimas para hacer esto. Depende de si va a ser o no una conversión de referencia frente a una conversión de unboxing o definida por el usuario.

Si se trata de una conversión de referencia, significa que el valor real (la referencia) permanecerá sin cambios. Todo lo que hace el reparto es realizar una verificación y luego copiar el valor. Eso no tiene un uso real: puede realizar la verificación usando Type.IsAssignableFrom en su lugar, y simplemente use el lanzamiento implícito a object si lo desea en una variable del tipo object.

El principal punto de la fundición es proporcionar el compilador con más información. Ahora bien, si solo conoce el tipo en ejecución vez, eso claramente no puede ayudar al compilador.

¿Qué piensas hacer con o después de que hayas realizado el reparto? Si puede explicar eso, podemos tratar de explicar cómo lograr el efecto que busca.

Si realmente desea una conversión definida por el usuario o una conversión unboxing a ocurrir, que podría ser un asunto diferente - pero sospechoso ese no es el caso.

EDIT: Después de haber visto a su actualización, su propiedad se acaba de declarar que volver CustomClass, por lo que todo lo que necesita es:

public CustomClass MyClassOuter 
{ 
    get 
    { 
     return (CustomClass) otherClass; 
    } 
} 

que usted sospecha que todavía no han realmente nos ha dado toda la información que necesitamos. ¿Es definitivamente cómo se definirá su propiedad, siendo CustomClass un tipo definido? ¿Por qué intentabas realizar el reparto dinámicamente cuando conoces el tipo de propiedad?

EDITAR: Parece que solo está tratando de guardar algo de escritura, para que sea más fácil cortar y pegar. No lo hagas Ya conoce el tipo en tiempo de compilación, porque conoce el tipo de propiedad en tiempo de compilación (está especificado en el código unas pocas líneas arriba). Usa ese tipo directamente. Del mismo modo, no intente obtener el nombre del método actual para calcular la clave que va a usar. Solo ingrese el nombre directamente. De nuevo, lo sabes en tiempo de compilación, entonces ¿por qué ser dinámico?Estoy a favor de la pereza cuando tiene sentido, pero en este caso simplemente no.

+0

He actualizado la pregunta para mostrar el contexto –

+0

He actualizado mi respuesta para responder. –

+0

Me puede estar faltando el punto aquí, pero parece que está tratando de crear un "obtener" genérico para las propiedades en cualquier clase. Dado que las propiedades no tienen nombre, no veo cómo esto podría funcionar, pero estoy feliz de haberme educado aquí. – Lazarus

1

No estoy del todo seguro de lo que estamos tratando de hacer , pero la impresión que me da es que te gustaría tener una sola instancia de algún objeto que pueda "actuar como" muchos tipos diferentes de objetos, y quieres tener getters que te permitan ver este objeto en esas varias maneras diferentes muy fácilmente. En ese caso, sugeriría hacer un solo método getter (no una propiedad), así:

public T Get<T>() 
{ 
    return (T)myObject; 
} 

allí tendría que llamarlo así:

Foo foo = box.Get<Foo>(); 
Bar bar = box.Get<Bar>(); 
// etc... 

Dos cosas a tener en cuenta: esto es definitivamente no es seguro para tipos, ya que puedes pasar cualquier tipo de T, incluidos los tipos para los que fallará el lanzamiento. Es posible restringir un poco, así:

public T Get<T>() where T : SomeBaseType 

lo que provocará un error de compilación si se intenta utilizar un tipo que es incompatible con SomeBaseType, pero no estoy seguro de que es totalmente sólida. Pero espero que esto te lleve la mayor parte del camino hasta allí.

¿Es esto lo que tenía en mente?

Cuestiones relacionadas