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

时间:2014-03-05 10:13:13

标签: c# wpf switch-statement

基本上,我有一个系统,我的datagrid标记已更改为新背景颜色的单元格,为此我在对象中有一个方法,包含这些属性,接收一个字符串,该字符串是属性的名称检查,然后使用该字符串检查正确属性的switch语句。

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

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

现在我得到的唠叨的感觉,有一个更清洁的方式来做到这一点串>物业不使用switch语句,但我不能为我的生活找到谷歌什么,很难没有一些关键字来进行搜索继续。

我也试图只保存那些已更改的属性,我将任何已更改的属性名称放入一个数组中,然后使用另一个switch语句循环检查该数组,然后保存正确的属性。然而,这对我来说再次显得不整齐。

是否有更清晰的解决方案,希望能够处理添加新属性而无需在switch语句中添加新代码。

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

3 个答案:

答案 0 :(得分:6)

您可以编写如下的扩展方法:

public static object GetPropValue(this object o, string propName)
{
    return o.GetType().GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
            .GetValue(o);
}

并使用它

if(localShipment.GetPropValue(value).Equals(originalShipment.GetPropValue(value)))
{
}

答案 1 :(得分:2)

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

var properties = new Dictionary<string, IProperty>();

并像这样访问它们:

properties["CILRef"]

答案 2 :(得分:2)

我会说switch声明很好,但是,您可以使用condition operator

在单行中执行case的正文
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方法来实现

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

仔细查看您的代码,看起来您确实在比较每次发货时的相同属性,您可以使用反射

将其简化为一次检查
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;
}

为简洁起见,您可以创建一个扩展方法来包装Reflection部分

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;