I've run into an issue where I need to get the name of a property for logging purposes. I'm sure there is a way to do this in VB.Net using some amalgam of reflection and lambda expressions, but I've been unsuccessful so far.
What I'm trying to do is convert this:
objAddress.AddressLine
to this:
"AddressLine"
In the past, I've used a method I found online for doing this with INotifyPropertyChanged
. I can't remember exactly where, but this details the same resolution:
http://paulstovell.com/blog/strong-property-names
C#
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
RaisePropertyChanged(() => Name);
}
}
private void RaisePropertyChanged(Expression<Func<object>> property)
{
MemberExpression exp = property.Body as MemberExpression;
if (exp != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(exp.Member.Name));
}
}
}
VB
Public Class Test
Implements INotifyPropertyChanged
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(value As String)
_Name = value
RaisePropertyChanged(Function() Me.Name)
End Set
End Property
Private Sub RaisePropertyChanged(Of T)(propertyName As Expression(Of Func(Of T)))
Dim exp As MemberExpression = TryCast(propertyName.Body, MemberExpression)
If exp IsNot Nothing Then
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(exp.Member.Name))
End If
End Sub
End Class
The main benefit of doing this is refactoring. If I ever rename my property, the Lambda (and by extension NotifyPropertyChanged event) changes automatically.
Update (2015)
It may be worth mentioning that the new features in Visual Studio 2015 make this even easier. Below is the same code shown above, but using the new nameof
feature (Details of this, and of other new features can be found Here).
C#
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
RaisePropertyChanged(nameof(Name));
}
}
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
VB
Public Class Test
Implements INotifyPropertyChanged
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(value As String)
_Name = value
RaisePropertyChanged(NameOf(Name))
End Set
End Property
Private Sub RaisePropertyChanged(propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
You can even use nameof
on the subscriber side, in order to determine if the property is the one you care about:
private static void PropChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Test.Name))
{
Console.WriteLine("The Property I care about changed");
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments