首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >替换开关语句-通过字符串名称获取属性

替换开关语句-通过字符串名称获取属性
EN

Stack Overflow用户
提问于 2014-03-05 10:13:12
回答 3查看 272关注 0票数 0

基本上,我有一个系统,我的数据标记单元格用新的背景颜色改变了,为此,我在对象中有一个包含这些属性的方法,该方法接收一个字符串,该字符串是要检查的属性的名称,然后是一个开关语句,它接受该字符串来检查正确的属性。

代码语言:javascript
运行
复制
public Color HasChanged(string value)
{
    switch (value)
    {
        case "CILRef":
            if (_localShipment.cilRef != _originalShipment.cilRef)
            {
                return Colors.SkyBlue;
            }
            else
            {
                return Colors.White;
            }
        case "ArrivedAtPortDate":
            if (_localShipment.arrivedAtPortDate != _originalShipment.arrivedAtPortDate)
            {
                return Colors.SkyBlue;
            }
            else
            {
                return Colors.White;
            }
    }
}

为了简洁起见,我删除了其余的属性。

现在我有了一种恼人的感觉,那就是在不使用开关语句的情况下,有一种更干净的方法来做这个string>property,但是我一辈子都无法在谷歌上找到任何东西,没有关键字就很难继续搜索。

我还试图只保存那些已更改的属性,我打算将任何更改的属性名称放入数组中,然后使用另一个switch语句进行循环,该语句检查该数组,然后保存正确的属性。然而,在我看来,这又是一种混乱。

是否有一个更清晰的解决方案,希望可以处理新属性的添加,而不需要添加新的代码到开关语句。

如果需要的话,我可以包括执行此检查的其余代码(即datagrid上的WPF绑定,以及调用以属性名称作为字符串参数的检查方法的转换器)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-05 10:26:59

您可以编写一个扩展方法,如:

代码语言:javascript
运行
复制
public static object GetPropValue(this object o, string propName)
{
    return o.GetType().GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
            .GetValue(o);
}

并使用它

代码语言:javascript
运行
复制
if(localShipment.GetPropValue(value).Equals(originalShipment.GetPropValue(value)))
{
}
票数 6
EN

Stack Overflow用户

发布于 2014-03-05 10:21:34

您可以为属性定义一个公共接口,然后创建一个属性字典,如下所示:

代码语言:javascript
运行
复制
var properties = new Dictionary<string, IProperty>();

像这样访问他们:

代码语言:javascript
运行
复制
properties["CILRef"]
票数 2
EN

Stack Overflow用户

发布于 2014-03-05 10:24:51

我会说switch语句很好,但是您可以使用条件算子在单行中完成case的主体操作。

代码语言:javascript
运行
复制
switch (value)
{
    case "CILRef":
        return _localShipment.cilRef != _originalShipment.cilRef ? Colors.SkyBlue : Colors.White;
    case "ArrivedAtPortDate":
        return _localShipment.arrivatedAtPortDate != _originalShipment.arrivedAtPortDate ? Colors.SkyBlue : Colors.White;
    ...
}

但是这里仍然有重复的代码,您可以更进一步,并有一个GetColor方法,该方法在

代码语言:javascript
运行
复制
public Colors GetColor(Func<bool> condition)
{
    return condition() ? Colors.SkyBlue : Colors.White;
}
...
switch (value)
{
    case "CILRef":
        return GetColor(() => _localShipment.cilRef != _originalShipment.cilRef);
    case "ArrivedAtPortDate":
        return GetColor(() => _localShipment.arrivatedAtPortDate != _originalShipment.arrivedAtPortDate);
}

仔细观察您的代码,看起来您确实是在比较每次发送的相同属性,您可以使用反射将此简化为一次检查。

代码语言:javascript
运行
复制
public Color HasChanged(string value)
{
    var date1 = _localShipment.GetType()
        .GetProperty(value)
        .GetValue(_localShipment, null);
    var date2 = _originalShipment.GetType()
        .GetProperty(value)
        .GetValue(_originalShipment, null);
    return date1 != date2 ? Colors.SkyBlue : Colors.White;
}

为了简洁起见,您可以创建一个扩展方法来结束反射部分。

代码语言:javascript
运行
复制
public static T Get<T>(this object obj, string name)
{
    return obj.GetType().GetProperty(name).GetValue(obj, null);
}
...
return _localShipment.Get<DateTime>(value) != _originalShipment.Get<DateTime>(value) ? Colors.SkyBlue : Colors.White;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22194666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档