如何使用属性本身获取属性的名称

Lyk*_*fox 3 vb.net reflection lambda properties

我遇到了一个问题,我需要获取一个属性的名称用于记录目的.我确信在VB.Net中有一种方法可以使用一些反射和lambda表达式的混合,但到目前为止我还没有成功.

我要做的是转换这个:

objAddress.AddressLine
Run Code Online (Sandbox Code Playgroud)

对此:

"AddressLine"
Run Code Online (Sandbox Code Playgroud)

Obs*_*nix 5

在过去,我使用了我在网上找到的一种方法INotifyPropertyChanged.我不记得究竟在哪里,但是这个细节分辨率相同:

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));
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这样做的主要好处是重构.如果我重命名我的属性,Lambda(以及扩展名NotifyPropertyChanged事件)会自动更改.


更新(2015年)

值得一提的是,Visual Studio 2015中的新功能使这一过程变得更加容易.下面是上面显示的相同代码,但是使用了新nameof功能(详细信息以及其他新功能可以在此处找到).

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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

您甚至可以nameof在订阅方使用,以确定该属性是否是您关注的属性:

    private static void PropChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(Test.Name))
        {
            Console.WriteLine("The Property I care about changed");
        }
    }
Run Code Online (Sandbox Code Playgroud)