2012-02-23 4 views
5

Я извлекаю несколько свойств элемента управления. Вот как я использовал, чтобы получить свойство (с pinfo типа PropertyInfo):Получите отражением значение свойства, у которого получатель имеет необязательное значение

value = pinfo.GetValue(obj, nothing) 

Это работало хорошо, но теперь я столкнулся свойство, которое имеет дополнительное значение, и я получаю сообщение об ошибке говорит мне, что количество параметров неверно. Поэтому я изменил код на этот:

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

На данный момент, я не получал никаких сообщений об ошибках, но этот код не извлекает хорошее значение. Он работает только в том случае, если я заменяю Ничто по умолчанию, предоставленное имущественным доступом ...

Но я не знаю заранее, что это за значение по умолчанию! И этот код в функции, которая извлекает свойства, которые не имеют дополнительных значений, поэтому я не могу изменить код, особенно для одного случая.

Любая идея? Я работаю на .NET 2,0


EDIT: больше Precisions о случае, ведущей к проблеме

Вот пример имущества приводит к проблеме:

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 ' 

Edit: Согласно вашему комментарию, что целому числу не работает, я пока не знаю, как получить значение по умолчанию необязательного параметр в свойстве. Если вы знаете, что вы можете легко передать его, но в противном случае происходит следующее (обратите внимание на 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

+0

И последняя строка, которую вы написали, похожа на одну из моих попыток (второй блок кода в моем вопросе) – GianT971

+0

@ GianT971: Извините, пропустил, что вы используете .NET 2. Отредактировал свой ответ соответственно. –

1

Попробуйте следующий пример. Убедитесь, что объект имеет значение null, затем активируйте его с помощью активатора. Следующая программа находится в 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

+0

Если testObj никогда не будет пустым, то он должен работать, как ожидалось. Активатор - это дополнительная проверка, чтобы гарантировать, что значение не равно нулю. – Manas

Смежные вопросы