Class.PropertyName 上的 Switch-Case(不是值) [英] Switch-Case on Class.PropertyName (not value)

查看:38
本文介绍了Class.PropertyName 上的 Switch-Case(不是值)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样实现 INotifyPropertyChanged 的类:

I have a class which implements INotifyPropertyChanged like this:

public class Person : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;

    string _color;
    public string Color
    {
        get{ return _color; }
        set
        {
            _color = value;
            RaisePropertyChanged();
        }
    }

    ...        

    private void RaisePropertyChanged([CallerMemberName]string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

Color 属性设置器被调用时,它会调用 RaisePropertyChanged() 自动获取属性名称,即 "Color" 并使用它填充 PropertyChangedEventArgs.而不是您手动输入属性名称.

When the Color property setter is called, it calls RaisePropertyChanged() which automatically gets the property name i.e "Color" and uses that to populate PropertyChangedEventArgs. Instead of you manually typing in the property name.

这很好,因为它可以防止代码中可能出现的错误,因为您不必手动键入属性名称.在重构代码时也有帮助,因为您没有对任何字符串进行硬编码.

This is good because it prevents possible bugs in your code since you dont have to manually type the property name. Also helps when refactoring your code since you aren't hard-coding any strings.

我的问题
我有一个 PropertyChanged 的事件处理程序.如何在不将属性名称硬编码为字符串的情况下使用 switch-case 构造.所以是这样的:

My Question
I have an event handler for PropertyChanged. How can I use a switch-case construct without hard-coding the Property Names as strings. So something like this:

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

这可能吗?我想这样做是为了保持我上面提到的好处.

Is this possible? I want to do this so I can keep the benefits I mentioned above.

推荐答案

您可以使用 Expression> 来做您想做的事.

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

定义这个方法:

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

然后你可以这样写:

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. :-)

要在没有 switch 和凌乱的 if/then/else 的情况下获得类似 switch 的功能,你可以这样做:

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 */
    }
}

这篇关于Class.PropertyName 上的 Switch-Case(不是值)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆