Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列包含默认值时的SingleOrDefault()_C#_.net_Linq - Fatal编程技术网

C# 序列包含默认值时的SingleOrDefault()

C# 序列包含默认值时的SingleOrDefault(),c#,.net,linq,C#,.net,Linq,我偶然发现了一个有趣的场景,我找不到解决方案。假设我必须在序列中找到主元素(至少出现n/2+1次的数字,其中n是序列的大小)。这是我的实现: public static int FindMajorant(IList<int> numbers) { return numbers .GroupBy(x => x) .Where(g => g.Count() >= numbers.Count / 2 + 1) .Se

我偶然发现了一个有趣的场景,我找不到解决方案。假设我必须在序列中找到主元素(至少出现
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();
}
这是预期的行为


但是,如果序列中的主键为零(
0
),会发生什么情况?它将返回0,但这样,我如何确定它是作为默认值的
SingleOrDefault()
中的0,还是主值?也许,我可以使用
Single()
,但这会引发一个非常不相关的异常。我也可以抓住这个例外,但这对我来说似乎是个坏习惯。所以我的问题是,处理这种情况的首选方法是什么?

使用可为空的值,其中
null
表示没有主变量,而不是使用“0”表示。非常方便的是,
int?
的默认值是
null
,因此对代码所做的唯一更改是在调用
SingleOrDefault
之前获取一系列可为null的int

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();
}
公共静态int?FindMajorant(IList编号)
{
返回号码
.GroupBy(x=>x)
其中(g=>g.Count()>=numbers.Count/2+1)
.选择(g=>(int?)g.Key)
.SingleOrDefault();
}

您可以将结果投射到一个类型化对象,比如说
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;
        }
    }
publicstaticmajorantresult FindMajorant(IList编号)
{
返回号码
.GroupBy(x=>x)
.其中(g=>g.Count()>=numbers.Count/2+1)
.选择(g=>new MajorantResult(g.Key))
.SingleOrDefault();
}
公开课主要成绩
{
公共int密钥{get;}
public MajorantResult(整数键)
{
这个。键=键;
}
}

请注意,您可以将
numbers.Count/2+1
从查询中拉出来,放入一个变量中,以避免对每个组重新计算。@Servy不是
Count
IList的属性,因此它实际上没有被计算?@MichaelMcGriff他指的是整个表达式。@MichaelMcGriff您仍然是把它除以2,再加上一。正确的是,任何合理的
IList
实现都不会让io迭代集合以获取计数。@MichaelMcGriff编译器足够聪明,知道
number.count
可以在该委托的调用之间更改,这就是它无法避免每次重新计算它的原因。
    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;
        }
    }