找不到匹配项时从List <>返回默认值

时间:2019-06-04 16:43:44

标签: c# list

我试图找到一种更干净的方法,即在找不到匹配项时返回默认值。下面从LinqPad

展示了我写的一个最好地证明我的问题的示例。

因此,基本上,如果在列表Age中找不到给定的SingleOrDefault,则会正常返回null。因此,我不选择返回最高的null而不返回Threshold,而无论Age的值是多少。

但是,除了执行if或使用?? (null coalescing operator)之外,还有更干净的方法来实现这一目标吗?也许在get类的Age属性的settest内设置默认值?

void Main()
{
    var list = new List<test>()
    { 
        new test ( 55, 27 ),
        new test ( 56, 28),
        new test ( 57, 29),
        new test ( 59, 30),
        new test ( 60, 31) //60+
    };

    var res = list.SingleOrDefault(x => x.Age == 61);   

    if (res == null)
    {
        list.Max(l => l.Threshold).Dump();
    }
    else
    {
        res.Threshold.Dump();   
    }  
} 

class test
{
    public int Age 
    { 
        get;
        set;
    }   

    public int Threshold 
    {   
        get;
        set;
    }

    public test(int age, int threshold)
    {
        Age = age;
        Threshold = threshold;
    }
}

3 个答案:

答案 0 :(得分:5)

您可以使用LINQ的TypeError: Cannot read property 'use' of undefined 58 | ) { > 59 | this.numberOfDrafts$ = this.getNumberOfDraftsGQL.watch().valueChanges.pipe( | ^

DefaultIfEmpty()

答案 1 :(得分:1)

我想您想使用一种LINQ方法SingleOrMax,可以这样使用:

var res = list.SingleOrMax(x => x.Age == 61, x => x.Threshold);

第一个表达式是SingleOrDefault的谓词,第二个表达式根据需要选择用于查找max元素的键。

这里是:

public static TSource SingleOrMax<TSource, TMaxKey>(this IEnumerable<TSource> source,
    Func<TSource, bool> predicate, Func<TSource, TMaxKey> maxKeySelector)
{
    var result = source.SingleOrDefault(predicate);
    if (result != default) return result;
    var maxKeyComparer = Comparer<TMaxKey>.Default;
    TSource max = default;
    TMaxKey maxKey = default;
    int count = 0;
    foreach (var item in source)
    {
        var key = maxKeySelector(item);
        if (count == 0 || maxKeyComparer.Compare(key, maxKey) > 0)
        {
            max = item;
            maxKey = key;
        }
        count++;
    }
    // If you remove the line bellow, then rename this method to SingleOrMaxOrDefault
    if (count == 0) throw new InvalidOperationException("Sequence contains no elements");
    return max;
}

答案 2 :(得分:0)

您总是可以使用扩展方法,尽管这似乎有些过分。

public static Test SingleAgeOrMaxThreshold(this IEnumerable<Test> items, int age)
{
    Test max = null;
    foreach (Test t in items)
    {
        if (t.Age == age)
            return t;

        if (max == null || t.Threshold > max.Threshold)
            max = t;
    }

    return max;
}