2012-02-23 39 views
5

Tôi đang truy xuất một số thuộc tính của điều khiển. Dưới đây là cách tôi sử dụng để lấy tài sản (với pinfo loại PropertyInfo):Nhận phản ánh giá trị của thuộc tính có getter có giá trị tùy chọn

value = pinfo.GetValue(obj, nothing) 

Đó hoạt động tốt, nhưng bây giờ tôi đang phải đối mặt với một tài sản mà có một giá trị tùy chọn, và tôi nhận được một thông báo lỗi nói với tôi rằng số tham số không đúng. Vì vậy, tôi đã thay đổi mã của mình bằng cách này:

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

Tại thời điểm này, tôi không nhận được bất kỳ thông báo lỗi nào, nhưng mã này không lấy được giá trị tốt. Nó chỉ hoạt động nếu tôi thay thế Không có gì bằng giá trị mặc định được cung cấp bởi người truy cập thuộc tính ...

Nhưng tôi không biết trước giá trị mặc định này là gì! Và mã này là trong hàm truy xuất thuộc tính không có giá trị tùy chọn, vì vậy tôi không thể thay đổi mã đặc biệt cho trường hợp này hoặc trường hợp khác.

Bất kỳ ý tưởng nào? Tôi đang làm việc trên NET 2,0


EDIT: Nhiều hơn độ chính xác về trường hợp dẫn đến các vấn đề

Dưới đây là một ví dụ về tài sản dẫn đến các vấn đề:

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 

Với loại tài sản này, không có mã nào ở trên truy xuất chuỗi tốt.

đoán tốt nhất của tôi sẽ được thử mã đầu tiên cho các mục đích chung, nắm bắt những ngoại lệ thích hợp, và sau đó tự động lấy giá trị mặc định của tham số (Số trong trường hợp đó) và loại của nó, vì vậy mà tôi có thể gọi getValue với giá trị mặc định này.

Vì vậy, Làm cách nào tôi có thể truy xuất giá trị mặc định của thông số tùy chọn?

Trả lời

3

này hoạt động với các thông số tùy chọn:

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: Theo nhận xét của bạn rằng số nguyên không làm việc, tôi chưa không biết làm thế nào để có được một giá trị mặc định của tùy chọn tham số trong Thuộc tính. Nếu bạn biết nó, bạn có thể dễ dàng vượt qua nó, nhưng nếu không sau sẽ xảy ra (chú ý Int32.MinValue như mặc định thay vì 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: Nhờ @Rup bây giờ tôi biết rằng GetIndexParameters là phần còn thiếu. Vì vậy, sau đây nên làm việc cho bất kỳ loại tham số.

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

Xin chào, thx đã trả lời, nhưng cú pháp của bạn không hoạt động đối với tôi ... Trình biên dịch không thích dấu ngoặc (.NET 2.0). Thêm vào đó, ví dụ của bạn sẽ không hoạt động đối với tôi, vì hàm của tôi phải lấy về tất cả các thuộc tính của một cá thể đối tượng, và nó được gọi cho nhiều đối tượng khác nhau – GianT971

+0

Và dòng cuối cùng bạn viết tương tự với một trong các lần thử của tôi (khối thứ hai của mã trong câu hỏi của tôi) – GianT971

+0

@ GianT971: Xin lỗi, bỏ lỡ bạn đang sử dụng .NET 2. Đã chỉnh sửa câu trả lời của tôi cho phù hợp. –

1

Hãy thử ví dụ sau. Xác minh nếu đối tượng là null sau đó kích hoạt nó bằng cách sử dụng Activator. Chương trình sau đây có trong 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

Cám ơn câu trả lời của bạn, nhưng nó không phù hợp với những gì tôi cần, vì đối tượng không bao giờ bằng null, nên Activator sẽ không bao giờ được sử dụng – GianT971

+0

Nếu testObj sẽ không bao giờ được null, sau đó nó sẽ làm việc như mong đợi. Trình kích hoạt chỉ là một kiểm tra bổ sung để đảm bảo giá trị không phải là rỗng. – Manas

Các vấn đề liên quan