Switch-Case on Class.PropertyName (not value)

前端 未结 2 482
面向向阳花
面向向阳花 2021-02-06 10:31

I have a class which implements INotifyPropertyChanged like this:

public class Person : INotifyPropertyChanged {

    public event PropertyChangedEv         


        
相关标签:
2条回答
  • 2021-02-06 10:33

    You can use Expression<Func<T>> to do what you want.

    Define this method:

    private string ToPropertyName<T>(Expression<Func<T>> @this)
    {
        var @return = string.Empty;
        if (@this != null)
        {
            var memberExpression = @this.Body as MemberExpression;
            if (memberExpression != null)
            {
                @return = memberExpression.Member.Name;
            }
        }
        return @return;
    }
    

    Then you can write this:

    void Person_PropertyChanged(object sender, PropertyChangedEventArgs e){
        switch (e.PropertyName)
        {
            case ToPropertyName(() => Person.Color);
                //some stuff
                break;
            default:
                break;
        }
    }
    

    Now you have some strongly-typed joy. :-)


    To get switch-like functionality without switch and messy if/then/else you can do this:

    void Person_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        var @switch = new Dictionary<string, Action>()
        {
            { ToPropertyName(() => Person.Color), () => { /* some stuff */ } },
            { ToPropertyName(() => Person.Size), () => { /* some other stuff */ } },
            { ToPropertyName(() => Person.Shape), () => { /* some more stuff */ } },
        };
    
        if (@switch.ContainsKey(e.PropertyName))
        {
            @switch[e.PropertyName]();
        }
        else
        {
            /* default stuff */
        }
    }
    
    0 讨论(0)
  • 2021-02-06 10:47

    In C# 6.0, you can use the nameof() keyword.

    The keyword is replaced by string literals at compile time. So it's much better than using lambda expression with code that digs the name of your symbol at runtime on a performance point of view, and it also works with switch() statements:

    switch(e.PropertyName)
    {
        case nameof(Foo.Bar):
            break;
    }
    

    You will also get a compile time error if you change the name of the property in the class, but forget to change it in your switch statement. So this approach is much less bugprone.

    0 讨论(0)
提交回复
热议问题