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