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?
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)
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; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With