Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get by reflection the value of a property whose getter has an optional value

I am retrieving several properties of a control. Here is how I used to retrieve properties (with pinfo of type PropertyInfo):

value = pinfo.GetValue(obj, nothing)

That worked well, but now I am facing a property that has a optional value, and I get an error message telling me that the number of parameters is incorrect. So I changed my code by this one:

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

At this point, I didn't get any error message, but this code doesn't retrieve the good value. It only works if I replace Nothing by the default value provided by the property accessor...

But I don't know in advance what this default value is! And this code is within a function that retrieves properties that doesn't have optional values, so I cannot change the code especially for one case or another..

Any idea? I am working on .NET 2.0


EDIT: More precisions about the case leading to the problem

Here is an example of property leading to the problem:

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

With this kind of property, none of the codes above retrieve the good string.

My best guess would be to try the first code for general purposes, catch the appropriate exception, and then dynamically retrieve the default value of the parameter (Number in that case) and its type, so that I can call getValue with this default value.

So, How can I retrieve the default value of the optional parameter?

like image 780
GianT971 Avatar asked Oct 08 '22 14:10

GianT971


2 Answers

This works with optional parameters:

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 '

Edit: According to your comment that integer don't work, i yet don't know how to get a default value of an optional parameter in a Property. If you know it you can easily pass it, but otherwise following happens(note the Int32.MinValue as default instead of 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: Thanks to @Rup now i know that GetIndexParameters was the missing part. So following should work for any kind of parameter.

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)
like image 67
Tim Schmelter Avatar answered Oct 18 '22 02:10

Tim Schmelter


Try following example. Verify if object is null then activate it using Activator. Following program is in 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; }
}
like image 21
Manas Avatar answered Oct 18 '22 02:10

Manas