当序列包含默认值时,SingleOrDefault()

时间:2015-10-28 20:06:24

标签: c# .net linq

我偶然发现了一个有趣的场景,我无法找到解决方案。假设我必须在序列中找到majorant(数量至少发生n / 2 + 1次,其中n是序列的大小)。这是我的实施:

public static int FindMajorant(IList<int> numbers)
{
    return numbers
        .GroupBy(x => x)
        .Where(g => g.Count() >= numbers.Count / 2 + 1)
        .Select(g => g.Key)
        .SingleOrDefault();
}

我使用SingleOrDefault(),如果在序列中找到该元素或该类型的默认值,则返回该元素:在这种情况下,它将返回0 as它是int的默认值。例如,我的方法返回3以获得以下序列:

List<int> sampleNumbers = new List<int>() { 2, 2, 3, 3, 2, 3, 4, 3, 3 };

这是预期的行为。

然而,如果序列中的主要部分为零(0)会发生什么?它会返回0,但是那样,我怎样才能确定它是SingleOrDefault()的零作为默认值,还是majorant?也许,我可以使用Single(),但这会引发一个非常不正常的例外。我也可以抓住这个例外,但这对我来说似乎是一个不好的做法。所以我的问题是,处理这种情况的首选方法是什么?

2 个答案:

答案 0 :(得分:8)

使用可以为空的值,其中null表示没有主要内容,而不是使用“0”表示。而且很方便,int?的默认值为null,因此您的代码所需的唯一更改是在调用SingleOrDefault之前获取一系列可为空的整数。

public static int? FindMajorant(IList<int> numbers)
{
    return numbers
        .GroupBy(x => x)
        .Where(g => g.Count() >= numbers.Count / 2 + 1)
        .Select(g => (int?)g.Key)
        .SingleOrDefault();
}

答案 1 :(得分:0)

您可以将结果投影到类型化的对象中说MajorantResult,然后返回null:

    public static MajorantResult FindMajorant(IList<int> numbers)
    {
        return numbers
            .GroupBy(x => x)
            .Where(g => g.Count() >= numbers.Count/2 + 1)
            .Select(g => new MajorantResult(g.Key))
            .SingleOrDefault();
    }

    public class MajorantResult
    {
        public int Key { get; }

        public MajorantResult(int key)
        {
            this.Key = key;
        }
    }