有没有办法将这些重复的代码变成一个单一的、干净的方法

问题描述 投票:0回答:1

我的搜索逻辑中有以下代码,它引用旧数据库,其中匹配搜索的唯一方法是表行名称、Level-1、Level-2 等。

if (criteria.Levels.Contains("Level-1", StringComparer.CurrentCultureIgnoreCase))
{
    var filteredResult = allCachedItems
        .Where(x => !string.IsNullOrEmpty(x.Level1));

    resultsSet.AddRange(filteredResult.Except(resultsSet));
}

if (criteria.Levels.Contains("Level-2", StringComparer.CurrentCultureIgnoreCase))
{
    var filteredResult = allCachedItems
        .Where(x => !string.IsNullOrEmpty(x.Level2));

    resultsSet.AddRange(filteredResult.Except(resultsSet));
}

if (criteria.Levels.Contains("Level-3", StringComparer.CurrentCultureIgnoreCase))
{
    var filteredResult = allCachedItems
        .Where(x => !string.IsNullOrEmpty(x.Level3));

    resultsSet.AddRange(filteredResult.Except(resultsSet));
}

显然这看起来很糟糕并且是重复的代码,所以我想创建一个可以接受字符串的方法,例如“Level-1”和某种委托来确定要测试模型上的哪些属性。

或者是一种更干净的方法来过滤我的“allCachedItems”集合。

该表有许多名为 Level{X} 的列,每个列在适合记录的地方包含一些文本,在不适合的地方为空。

搜索表单以“Level-{x}”格式传递纯文本。

c# function linq delegates refactoring
1个回答
1
投票

试一试:

void AddCachedLevel(string level, Func<Item, string> property)
{
    if (criteria.Levels.Contains(level, StringComparer.CurrentCultureIgnoreCase))
    {
        var filteredResult = allCachedItems.Where(x => !string.IsNullOrEmpty(property(x)));
        resultsSet.AddRange(filteredResult.Except(resultsSet));
    }
}

AddCachedLevel("Level-1", x => x.Level1);
AddCachedLevel("Level-2", x => x.Level2);
AddCachedLevel("Level-3", x => x.Level3);

或者这个,如果

resultsSet
最初是空的:

List<Item> resultsSet =
(
    from x in allCachedItems
    where
        criteria.Levels.Contains("Level-1", StringComparer.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(x.Level1)
        || criteria.Levels.Contains("Level-2", StringComparer.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(x.Level2)
        || criteria.Levels.Contains("Level-3", StringComparer.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(x.Level3)
    select x
).ToList();

或者这个,如果你想要两者的组合:

bool Check(Item item, string level, Func<Item, string> property) =>
    criteria.Levels.Contains(level, StringComparer.CurrentCultureIgnoreCase)
    && !string.IsNullOrEmpty(property(item));
    
List<Item> resultsSet =
(
    from item in allCachedItems
    where
        Check(item, "Level-1", x => x.Level1)
        || Check(item, "Level-2", x => x.Level2)
        || Check(item, "Level-3", x => x.Level3)
    select item
).ToList();
© www.soinside.com 2019 - 2024. All rights reserved.