2012-02-23 97 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