2015-07-23 2 views
0

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

Например:

Public Class_1 

    Public a1 as string = "" 

    Public Sub New() 
     ' when a button is clicked call subroutine "check()" 
    End Sub 

End Class 

Public Class_2 

    Public a1 as string = "" 
    Public a2 as integer = 0 

    Public Sub New() 
     ' when a button is clicked call subroutine "check()" 
    End Sub 

End Class 

Public Class whatever 

    Public Sub check(sender as object) 
     If sender.a2 = 0 then 
     ' do something 
     End if 
    End Sub 

End Class 

Я попытался такие вещи, как

If not(sender.a2 is nothing) then 
If isnothing(sender.a2) then 

Но я не могу пройти мимо того факта, что я получаю сообщение об ошибке, просто используя «sender.a2», так как a2 не всегда является участником отправителя.

Как проверить, не является ли a2 членом класса отправки без использования «sender.a2»?

+2

OOP позволяет перегружать методы. Вместо того, чтобы определять его как «Подтвердить (отправитель как объект)», используйте реальные типы и определите кратность. Внутри вы можете вызвать какой-то общий метод, но это позволит 'Sub check (sender as Class_2)' делать определенные вещи Class_2 по мере необходимости. Вы можете использовать отражение или gettype, возможно, чтобы определить, с чем работаете, но было бы лучше исправить код, чтобы быть более OO. Наследование или интерфейсы могут также решить эту проблему. – Plutonix

+0

Возможный дубликат [Проверить, что объект имеет определенное свойство] (http://stackoverflow.com/questions/9399872/verify-that-an-object-has-a-certain-property) –

+2

Вы можете создать интерфейс, это свойство и реализовать этот интерфейс при использовании свойства. Тогда вам просто нужно протестировать и применить свой объект к этому интерфейсу. Или, если вы поместите свою функцию проверки внутри своих классов, у вас может не возникнуть проблема в конце концов. –

ответ

2

Если вы хотите увидеть, что поле существует вам это нужно:

Dim fi As FieldInfo = sender.GetType().GetField("nameOfFieldHere") 
If fi IsNot Nothing 
    'field exists now get the value 
    Dim o As Object = fi.GetValue(sender) 
End If 

Посмотрите на документацию Type.GetField Method (String) Есть также перегружает слишком доступны.

+0

Это не поле, это «член», поскольку ошибка говорит: «a2 не является членом класса ...« – user2721815

+0

Это, безусловно, поле. Проблема заключается в том, что отправитель передается как объект, который не имеет этого поля, но фактический базовый тип объекта (' Class_1' или 'Class_2') делает ошибку. – Ric

+0

Ваше закрытие, но я думаю, что мне нужно GetMember не GetField. – user2721815

0

Вы можете проверить, что объект, на который вы ссылаетесь, имеет определенный тип, прежде чем пытаться его использовать. После того, как вы определили, что это правильный тип, вы можете смело бросить на него, а затем использовать правильные свойства, как так:

If (TypeOf sender Is Class_2) Then 
    Dim castObj As Class_2 = CType(sender, Class_2) 
    'We can now access castObj.a2 
End If 

Если существует несколько классов со свойством, было бы целесообразно создать интерфейс, который заявляет, что у них есть свойство a2 и все они реализуют его. Затем вы можете проверить свой тип на новый интерфейс вместо Class_2.

Альтернативный вариант - использовать наследование классов для реализации общедоступного метода по умолчанию для всех классов и переопределить его в специальном случае Class_2 для ваших подклассов.

+0

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

+1

Именно по этой причине вы, вероятно, захотите использовать что-то, что связывает все классы вместе, например, интерфейс или базовый класс. – Ric

+0

Как сказал @Ric, вы можете просто протестировать интерфейс, который наследует ваш поднабор классов. Это должно быть более эффективным, чем отражение в ответе Рика, и имеет дополнительное преимущество, заключающееся в том, что оно безопасно для рефакторинга, поскольку у вас нет имени поля, плавающего вокруг в строке, которую нужно запомнить. – Wibbler

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