Normally, to access one specific property (rather than enumerating all of them
as is done for e.g. the form designer's properties view), you wouldn't use
GetProperties. We can therefore simplify the code:
Private Shared Function GetPropertyValueByName(Of TObject, TProperty) (
ByVal T As TObject,
ByVal PropertyName As String) As TProperty
Dim result = GetType(TObject).GetProperty(PropertyName, GetType(Property), {})
If (result IsNot Nothing) Then
Return CType(result.GetValue(T), TProperty)
End If
Return Nothing
End Function
Since CLI types can only have a single property with a given name (you can't
have multiple properties overloaded by return type), you can simplify this
further if you're willing to accept that you may be getting a property of some
other type and then casting it to the TProperty type.
Private Shared Function GetPropertyValueByName(Of TObject, TProperty) (
ByVal T As TObject,
ByVal PropertyName As String) As TProperty
Const flag = BindingFlags.Public Or BindingFlags.Instance or BindingFlags.GetProperty
Dim value = GetType(TObject).InvokeMember(PropertyName, flag, Nothing, T, {})
Return CType(value, TProperty)
End Function
If you want to return Nothing if the property is not found or has the wrong
type, you will need to catch exceptions.
You can also avoid passing in TObject by simply using the .GetType()
method on the object, but that changes the semantics further.
NOTE: It's been a while since I've coded in VB, and I'm not 100% sure that {}
is the correct syntax for an empty array whose type can be inferred. It is intended as an empty array of Type in the first example, and of Object in the second example.