2012-02-23 30 views
5

Estoy recuperando varias propiedades de un control. Aquí es cómo he utilizado para recuperar propiedades (con pinfo de tipo PropertyInfo):Obtener por reflexión el valor de una propiedad cuyo getter tiene un valor opcional

value = pinfo.GetValue(obj, nothing) 

que han funcionado bien, pero ahora estoy frente a una propiedad que tiene un valor opcional, y me sale un mensaje de error que me dice que el número de parámetros es incorrecto Así que cambié mi código por éste:

Dim index As Object() = {Nothing} 
value = pinfo.GetValue(obj, index) 

En este momento, no he tenido ningún mensaje de error, pero este código no recupera el valor. Sólo funciona si reemplazo Nada por el valor predeterminado proporcionado por el descriptor de acceso a la propiedad ...

¡Pero no sé de antemano cuál es este valor predeterminado! Y este código es dentro de una función que recupera propiedades que no tienen valores opcionales, por lo que no puedo cambiar el código especialmente para un caso u otro ..

¿Alguna idea? Estoy trabajando en .NET 2,0


EDIT: Más precisiones sobre el caso que lleva al problema

Este es un ejemplo de la propiedad que lleva al problema:

ReadOnly Property Foo(Optional ByVal Number As Integer = -1) As String 
    Get 
     If Number = -1 Then 
      Return "Your number is the default number: " & Number 
     Else 
      Return "Your number is " & Number 
     End If 
    End Get 
End Property 

Con este tipo de propiedad, ninguno de los códigos anteriores recupera la buena cadena.

Mi mejor conjetura sería intentar el primer código de propósito general, detectar la excepción apropiada, y luego recuperar dinámicamente el valor predeterminado del parámetro (Número en este caso) y su tipo, por lo que yo puede llamar al getValue con este valor predeterminado.

Entonces, ¿cómo puedo recuperar el valor predeterminado del parámetro opcional?

Respuesta

3

Esto funciona con parámetros opcionales:

ReadOnly Property Foo(Optional name As String = Nothing) As String 
    Get 
     If name Is Nothing Then 
      Return "Hello World" 
     Else 
      Return "Hello " & name 
     End If 
    End Get 
End Property 


Dim pinfo As Reflection.PropertyInfo = Me.GetType().GetProperty("Foo") 
Dim value As Object = pinfo.GetValue(Me, New Object() {"Tim"}) ' Hello Tim ' 
value = pinfo.GetValue(Me, New Object(){Nothing})    ' Hello World ' 

Editar: De acuerdo con su comentario de que un entero no funcionan, yo todavía no sé cómo conseguir un valor por defecto de un opcional parámetro en una propiedad. Si usted sabe que puede pasar fácilmente, pero por lo demás ocurre lo siguiente (nótese el Int32.MinValue como predeterminado en lugar de 0):

ReadOnly Property Foo(Optional age As Int32 = Int32.MinValue) As String 
    Get 
     If age = Int32.MinValue Then 
      Return "I don't know how old i am" 
     Else 
      Return String.Format("I am {0} years old", age) 
     End If 
    End Get 
End Property 

Dim pinfo As Reflection.PropertyInfo = Me.GetType.GetProperty("Foo") 
Dim value As Object = pinfo.GetValue(Me, New Object() {38}) ' I am 38 years old ' 
value = pinfo.GetValue(Me, New Object() {Nothing})   ' I am 0 years old ' 
value = pinfo.GetValue(Me, New Object() {Int32.MinValue}) ' I don't know how old i am ' 

Edit2: Gracias a @Rup Ahora sé que fue el GetIndexParameters parte que falta. Entonces, el siguiente debería funcionar para cualquier tipo de parámetro.

Dim pinfo As Reflection.PropertyInfo = Me.GetType.GetProperty("Foo") 
Dim parameters() As Reflection.ParameterInfo = pinfo.GetIndexParameters() 
Dim params(parameters.Length - 1) As Object 
For i As Int32 = 0 To parameters.Length - 1 
    Dim paramInfo As Reflection.ParameterInfo = parameters(i) 
    If paramInfo.IsOptional Then 
     params(i) = paramInfo.DefaultValue 
    Else 
     If paramInfo.ParameterType.IsValueType Then 
      params(i) = Activator.CreateInstance(paramInfo.ParameterType) 
     Else 
      params(i) = Nothing 
     End If 
    End If 
Next 
Dim value As Object = pinfo.GetValue(Me, params) 
+0

Hola, gracias por responder, pero tu sintaxis no funciona para mí ... Al compilador no le gustan las llaves (.NET 2.0). Además, su ejemplo no funcionará para mí, ya que mi función debe recuperar el sobre todas las propiedades de una instancia de objeto, y se llama para muchos objetos diferentes. – GianT971

+0

Y la última línea que escribió es similar a uno de mis intentos (el segundo bloque de código en mi pregunta) – GianT971

+0

@ GianT971: Perdón, extrañé que estás usando .NET 2. Edité mi respuesta en consecuencia. –

1

Pruebe el siguiente ejemplo. Verifique si el objeto es nulo y actívelo con el Activador. El siguiente programa está en C#.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Test testObj = null; 
     testObj = testObj ?? Activator.CreateInstance<Test>(); 
     var ty = testObj.GetType().GetProperty("MyProperty").GetValue(testObj, null); 

    } 
} 
public class Test 
{ 
    public Test2 MyProperty { get; set; } 
} 
public class Test2 
{ 
    public int Prty { get; set; } 
} 
+0

Gracias por su respuesta, pero no encaja con lo que necesito, porque el objeto no es igual a cero, por lo que el activador no se utilizaría – GianT971

+0

Si testObj nunca será nula, entonces debería funcionar como se esperaba. El activador es solo un control adicional para garantizar que el valor no sea nulo. – Manas

Cuestiones relacionadas