2012-02-23 96 views
5

我正在检索控件的多个属性。这里是我用来检索性能(与类型的PropertyInfo的PINFO):通过反射获取属性的值,该属性的getter具有可选值

value = pinfo.GetValue(obj, nothing) 

运行良好,但现在我面对的是具有可选值的属性,我得到一个错误消息,告诉我,参数数量不正确。所以,我这个一个改变了我的代码:

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

在这一点上,我没有得到任何错误消息,但是这个代码不检索物有所值。它只有当我更换没有由属性访问器提供的默认值...

的作品,但我事先不知道这个默认值是什么!并且此代码是内功能检索不具有可选值的属性,所以我不能更改代码,特别是对于一种情况或另一种情况..

任何想法?我工作的.NET 2.0


编辑:更多关于精度导致问题

这里的情况是财产导致问题的例子:

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 

随着这种属性,上面的代码都没有检索到好的字符串。

我最好的猜测是尝试一般用途的第一个代码,赶上合适的异常,然后动态检索参数(在这种情况下号)和其类型默认值,让我可以用此默认值调用getValue

那么,我该如何检索可选参数的默认值?

回答

3

这适用于可选参数:

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 ' 

编辑:根据您的评论该整数不工作,但我不知道如何让一个可选的默认值参数在属性中。如果你知道它,你可以很容易地通过它,否则会发生以下情况(注意Int32.MinValue为默认值,而不是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:由于现在@Rup我知道GetIndexParameters是遗失的部分。所以以下应该适用于任何类型的参数。

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

嗨,thx回答,但你的语法不适合我......编译器不喜欢大括号(.NET 2.0)。另外,你的例子不适用于我,因为我的函数必须检索一个对象实例的所有属性,并且它被调用许多不同的对象。 – GianT971 2012-02-23 17:35:18

+0

你写的最后一行与我的一次尝试类似第二块代码在我的问题) – GianT971 2012-02-23 17:36:32

+0

@ GianT971:对不起,错过了你使用.NET 2.相应地编辑我的答案。 – 2012-02-23 19:31:26

1

请尝试以下示例。验证对象是否为空,然后使用激活器激活它。 以下程序在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

谢谢您的回答,但它不适合与我所需要的,因为对象总是不等于空,所以激活将永远不会被使用 – GianT971 2012-02-23 17:13:24

+0

如果testObj永远不会为空,那么它应该工作正常。激活器只是一个额外的检查,以确保值不为空。 – Manas 2012-02-23 17:25:40