lundi 16 mars 2015

Expression(Of Func(Of T)).Body.Member.Name bizarre "$vb$local_" added if used inside a Property Get Accessor

Apparently I have an old VB .Net project to maintain.


I don't feel so comfortable to exclaim in public that I'm still (sometimes) using VB... But haven't really got a choice now as I need to make the following bizarre behavior public, and see if anyone already came this across. In fact, I did quite a bit of searching, but have not bumped in anything related as yet.


It has somehow got quite conventional to supply a reference to a Property name from within a Class to a Method by means of a Lambda expression, instead the name String itself. So: RaisePropertyChanged("myProperty") gets RaisePropertyChanged(() => myProperty) in C# or RaisePropertyChanged(Function() myProperty) in VB .Net.


The called Method receives that Lambda expression in a System.Linq.Expressions.Expression<Func<T>> type in C# or Expression(Of Func(Of T)) in VB .Net.


In order the get the Property name in a String representation, the called Method retrieves the Expression(Of Func(Of T)).Body as a MemberExpression. Then accessing memberExprisson.Member.Name will usually get the proper Property name.


However, in VB .Net I have noticed the following bizarre behavior: When calling a method inside of Property Get stub supplying a Property by means such as (Function() myProperty) the memberExprisson.Member.Nameresults to: "$VB$Local_myProperty". So that's $VB$Local_ added in front of the Property name. Calling however from the Property Set stub worked as intended.


Whats more, when the result is OK, the memberExpression.Member'type is a System.Reflection.RuntimePropertyInfo. Whereas when the bizarre "$VB$Local_" is added, the memberExpression.Member results in a System.Reflection.RtFieldInfo type.


When examining the Expression Property of the above mentioned memberExpression thus: memberExpression.Expression, I find that the Type Property thereof will - on good behavior - have the proper Container Class name. On erroneous behavior however, that Type property will have a 'FullName' Property of something like "_Closure$__X" + the Container (Declaring) Class name. Further looking inside this Type property reveals that this FullName consist of a the Name of the Type itself which is "_Closure$__X" combined with the 'ReflectedType' which contains the proper Class name, resulting in this strange FullName. This "_Closure$__X" by the way, The 'X' represents a Number. It will be '1' inside the first Property Get stub and 2 for the second and so forth. So: "_Closure$__1", "_Closure$__2"...


Any comments?






Aucun commentaire:

Enregistrer un commentaire