title: Expression(Of Func(Of T)).Body.Member.Name bizarre "$vb$local_" added if used inside a Property Get Accessor
body: <p>I have observed the following bizarre behavior, and want to see if anyone already came across the same. In fact, I did quite a bit of searching, but have not bumped in anything related as yet.</p>
  
  <p>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: <code>RaisePropertyChanged("myProperty")</code> gets <code>RaisePropertyChanged(() =&gt; myProperty)</code> in C# or <code>RaisePropertyChanged(Function() myProperty)</code> in VB .Net.</p>
  
  <p>The called Method receives that Lambda expression in a <code>System.Linq.Expressions.Expression&lt;Func&lt;T&gt;&gt;</code> type in C# or <code>Expression(Of Func(Of T))</code> in VB .Net.</p>
  
  <p>In order the get the Property name in a String representation, the called Method retrieves the <code>Expression(Of Func(Of T)).Body</code> as a <code>MemberExpression</code>. Then accessing <code>memberExprisson.Member.Name</code> will usually get the proper Property name.</p>
  
  <p>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 <code>(Function() myProperty)</code> the <code>memberExprisson.Member.Name</code>results 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.</p>
  
  <p>Whats more, when the result is OK, the <code>memberExpression.Member</code>'type is a <code>System.Reflection.RuntimePropertyInfo</code>. Whereas when the bizarre "$VB$Local_" is added, the <code>memberExpression.Member</code> results in a <code>System.Reflection.RtFieldInfo</code> type.</p>
  
  <p>When examining the Expression Property of the above mentioned <code>memberExpression</code> thus: <code>memberExpression.Expression</code>, I find that the <code>Type</code> 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"...</p>
  
  <p>Any comments?</p>
  
  <p>EDIT:</p>
  
  <p>For clarity here is a snapshot of the code:</p>
  
  <pre><code>Public Property RegisteredServer As Result
      Get
          Return GetProperty(Of Result)(Function() RegisteredServer)
      End Get
      Set(value As Result)
          SetProperty(Of Result)(Function() RegisteredServer, value)
      End Set
  End Property
  
  Public Property DefaultInstance As Result
      Get
          Return GetProperty(Function() DefaultInstance)
      End Get
      Set(value As Result)
          SetProperty(Function() DefaultInstance, value)
      End Set
  End Property
  </code></pre>
  
  <p><code>GetProperty</code>And <code>SetProperty</code> are defined in the following code:</p>
  
  <pre><code>Private Function GetPropertyName(Of T)(propertyExpression As Expression(Of Func(Of T)))
      Dim memberExpr As MemberExpression = propertyExpression.Body
      If memberExpr Is Nothing Then
          Throw New ArgumentException("propertyExpression should represent access to a member")
      End If
      Dim memberName As String = memberExpr.Member.Name
      Return memberName
  End Function
  
  Shared Function CompareValues(Of T)(storage As T, value As T)
      Return Object.Equals(storage, value)
  End Function
  
  Protected Function SetProperty(Of T)(propertyExpression As Expression(Of Func(Of T)), value As T)
      Dim memberName As String = GetPropertyName(propertyExpression)
      Dim currentValue As T = Nothing
      _propertyBag.TryGetValue(memberName, currentValue)
      If CompareValues(currentValue, value) Then
          Return False
      End If
      _propertyBag(memberName) = value
      RaisePropertyChanged(memberName)
      Return True
  End Function
  
  Protected Function GetProperty(Of T)(propertyExpression As Expression(Of Func(Of T))) As T
      Dim memberName As String = GetPropertyName(propertyExpression)
      Dim value As T = Nothing
      _propertyBag.TryGetValue(memberName, value)
      Return value
  End Function
  </code></pre>
  
  <p>Hope this helps.</p>