It is not possible to use the extension method as directly as you tried, because the method applies only to types PropertyInfo
, and the property HelloWorld
is the type String
, so it is first necessary to obtain the PropertyInfo
of that property.
I did a research and saw that you can do this in a "manual" way, taking the type of class and then using the method GetProperty()
. You can do this using the name of the property, as a String
:
Dim propInfoManual As PropertyInfo = GetType(Foo).GetProperty("HelloWorld")
Or you can use the operator NameOf
, which avoids typing errors, which will be noticed already at compilation time:
Dim propInfoManual As PropertyInfo = GetType(Foo).GetProperty(NameOf(Foo.HelloWorld))
But, if you still want to do an extension method, you can do so, if you are going to pass the name of the property as a String
:
<Extension()>
Public Function GetPropInfo(Of T)(origem As T, prop As String) As PropertyInfo
Return GetType(T).GetProperty(prop)
End Function
If you want that advantage of strong typing, which makes it possible to catch typos at compile time, in this case the thing gets more complicated and the only way I found was by using the expression construction/deconstruction classes lambda:
' Necessário para usar as classes de expressões lambda.
Imports System.Linq.Expressions
'[...]
<Extension()>
Public Function GetPropInfo(Of TSource, TProp)(origem As TSource,
seletorProp As Expression(Of Func(Of TProp))
) As PropertyInfo
Select Case seletorProp.Body.NodeType
Case ExpressionType.MemberAccess
Dim memExp As MemberExpression = DirectCast(seletorProp.Body, MemberExpression)
Return DirectCast(memExp.Member, PropertyInfo)
Case Else
Throw New ArgumentException()
End Select
End Function
To test the three methods:
Public Class Foo
<Description("Hello world with space")>
Public Property HelloWorld As String
Public Function DescricaoPropriedade() As String
Dim descManual As String = GetType(Foo).GetProperty(NameOf(Foo.HelloWorld)).GetDescription()
Dim descExtStr As String = Me.GetPropInfo("HelloWorld").GetDescription()
Dim descExtLambda As String = Me.GetPropInfo(Function() Me.HelloWorld).GetDescription()
Return $"Desc manual: {descManual} {vbCrLf}" &
$"Desc estendido (str): {descExtStr} {vbCrLf}" &
$"Desc estendido (lambda): {descExtLambda}"
End Function
End Class
You can also use the extension method with lambda without the Me.
, I put it only to get more didactic.
Sources:
EDITION
At the time I did not visualize, but now I realized that it is possible to use the simplest extension solution, with parameter String
instead of expression lambda, and still have strong typing, using here also the operator NameOf
:
Dim descExtStr As String = Me.GetPropInfo(NameOf(HelloWorld)).GetDescription()