C# Linq组查询给出错误的结果

C# Linq组查询给出错误的结果,c#,linq,linq-group,C#,Linq,Linq Group,我在C#项目中使用group by子句执行Linq查询时遇到以下问题: public class Stock { public string Name {get; set;} public List<int> Values {get; set;} public float Price {get; set;} } // Stock collection List<Stock> stocks = new List<Stock>() {

我在C#项目中使用group by子句执行Linq查询时遇到以下问题:

public class Stock {
    public string Name {get; set;}
    public List<int> Values {get; set;}
    public float Price {get; set;}
}

// Stock collection
List<Stock> stocks = new List<Stock>()
{
    new Stock(){Name="Prod1", Values=new List<int>{1, 2, 3, 0}, Price=5.0f, 
    new Stock(){Name="Prod1", Values=new List<int>{1, 2, 3, 0}, Price=5.0f,
    new Stock(){Name="Prod11", Values=new List<int>{1, 0, 3, 1}, Price=8.0f,
    new Stock(){Name="Prod11", Values=new List<int>{1, 0, 3, 1}, Price=8.0f,
    new Stock(){Name="Prod18", Values=new List<int>{0, 0, 4, 1}, Price=4.5f,
    new Stock(){Name="Prod20", Values=new List<int>{4, 0, 0, 2}, Price=9.9f,
    new Stock(){Name="Prod20", Values=new List<int>{4, 0, 0, 2}, Price=9.9f,
    new Stock(){Name="Prod29", Values=new List<int>{2, 1, 0, 1}, Price=7.2f,
};

var query = stocks.GroupBy(x => x, (x, g) => new { Count = g.Count(), Values = x}).ToList();
公共类股票{
公共字符串名称{get;set;}
公共列表值{get;set;}
公开浮动价格{get;set;}
}
//存货收集
上市股票=新上市()
{
newstock(){Name=“Prod1”,value=newlist{1,2,3,0},Price=5.0f,
newstock(){Name=“Prod1”,value=newlist{1,2,3,0},Price=5.0f,
newstock(){Name=“Prod11”,value=newlist{1,0,3,1},Price=8.0f,
newstock(){Name=“Prod11”,value=newlist{1,0,3,1},Price=8.0f,
newstock(){Name=“Prod18”,value=newlist{0,0,4,1},Price=4.5f,
newstock(){Name=“Prod20”,value=newlist{4,0,0,2},Price=9.9f,
newstock(){Name=“Prod20”,value=newlist{4,0,0,2},Price=9.9f,
newstock(){Name=“Prod29”,value=newlist{2,1,0,1},Price=7.2f,
};
var query=stocks.GroupBy(x=>x,(x,g)=>new{Count=g.Count(),Values=x}).ToList();

此查询给出了错误的分组结果。

为了使
GroupBy
生成分组,分组所依据的对象必须具有
GetHashCode
等于
的覆盖,或者需要为
GroupBy
提供合适的相等比较器

您的
Stock
没有覆盖
GetHashCode
/
Equals
,并且您的
GroupBy
查询没有使用自定义的相等比较器,因此您会得到意外的结果

提供适当的覆盖将解决此问题:

public class Stock {
    public string Name {get; set;}
    public List<int> Values {get; set;}
    public float Price {get; set;}
    public override bool Equals(object obj) {
        if (obj == this) return true;
        var other = obj as Stock;
        if (other == null) return false;
        return Name.Equals(other.Name)
            && Price == other.Price
            && Values.SequenceEqual(other.Values);
    }
    public override int GetHashCode() {
        return Name.GetHashCode()
             + Price.GetHashCode()
             + Values.Sum();
    }
}
公共类股票{
公共字符串名称{get;set;}
公共列表值{get;set;}
公开浮动价格{get;set;}
公共覆盖布尔等于(对象对象对象){
如果(obj==this)返回true;
var other=作为股票的obj;
if(other==null)返回false;
返回Name.Equals(其他.Name)
&&价格=其他价格
&&值。SequenceEqual(其他值);
}
公共覆盖int GetHashCode(){
返回Name.GetHashCode()
+Price.GetHashCode()
+value.Sum();
}
}

请提供输入数据和预期分组结果的示例。您应该写出您预期的结果(即正确的结果)以及您从代码中实际得到的结果(即错误的结果)。这将帮助我们理解您的问题并回答您的问题。您是对的。我添加了样本数据。样本数据产生正确的结果。它确实提供了分组数据。重点是:尽管人们明确要求,但您从未定义“错误”(即预期与实际)。即使现在我也不知道您期望什么。Count()对我来说,给定您的查询,这是正确的。
Price.GetHashCode
缺少
()
,缺少2x
覆盖
关键字我尝试了您的代码。查询没有提供分组数据。