Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.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# IEnumerable.GroupBy未分组_C#_.net_Vb.net_Equality - Fatal编程技术网

C# IEnumerable.GroupBy未分组

C# IEnumerable.GroupBy未分组,c#,.net,vb.net,equality,C#,.net,Vb.net,Equality,我在.NET中使用GroupBy扩展时遇到问题(4.5,无论VB.NET还是C#。示例是C#)。情况如下: 2个示例类: public class Office : IEquatable<Office> { public String Name { get; set; } public int Id { get; set; } public String Stuff { get; set; } // Compare by values pub

我在.NET中使用GroupBy扩展时遇到问题(4.5,无论VB.NET还是C#。示例是C#)。情况如下:

2个示例类:

public class Office : IEquatable<Office>
{
    public String Name { get; set; }
    public int Id { get; set; }
    public String Stuff { get; set; }

    // Compare by values
    public bool Equals(object obj)
    {
        if (obj is Office)
        {
            Office cmp = (Office) obj;
            bool result = true;
            result &= cmp.Id == this.Id;
            result &= cmp.Name == this.Name;
            result &= cmp.Stuff == this.Stuff;
            return result;
        }
        else return false;
    }

    // Hashcode by values
    public int GetHashCode()
    {
        var obj = new { Id = this.Id, Name = this.Name, Stuff = this.Stuff };
        return obj.GetHashCode();
    }

    // IEquatable uses overriden Equals implementation
    bool IEquatable<Office>.Equals(Office other)
    {
        return this.Equals(other);
    }
}

public class Company
{
    public Office Office { get; set; }
    public String Name { get; set; }
}
公共类办公室:IEquatable
{
公共字符串名称{get;set;}
公共int Id{get;set;}
公共字符串填充{get;set;}
//按值比较
公共布尔等于(对象obj)
{
如果(obj是办公室)
{
办公室cmp=(办公室)obj;
布尔结果=真;
result&=cmp.Id==this.Id;
result&=cmp.Name==this.Name;
result&=cmp.Stuff==this.Stuff;
返回结果;
}
否则返回false;
}
//哈希值编码
public int GetHashCode()
{
var obj=new{Id=this.Id,Name=this.Name,Stuff=this.Stuff};
返回obj.GetHashCode();
}
//IEquatable使用覆盖的Equals实现
bool IEquatable.Equals(其他办公室)
{
返回此。等于(其他);
}
}
公营公司
{
公共办公室{get;set;}
公共字符串名称{get;set;}
}
类办公室重写了相等比较函数并实现了IEquatable接口,在这种情况下(据我所知),默认的EqualityComparer使用我的Equals实现

现在,我想根据公司所占的办公室将公司列表分组,如下所示:

        List<Company> companies = new List<Company>();
        Office office1 = new Office();
        office1.Id = 1;
        office1.Name = "Office";
        office1.Stuff = "Stuff";

        Office office2 = new Office();
        office2.Id = 1;
        office2.Name = "Office";
        office2.Stuff = "Stuff";

        Company date1 = new Company();
        date1.Office = office1;
        date1.Name = "Date 1";

        Company date2 = new Company();
        date2.Office = office2;
        date2.Name = "Date 2";

        companies.Add(date1);
        companies.Add(date2);

        IEnumerable<IGrouping<Office, Company>> grouping = companies.GroupBy(x => x.Office);

        Console.WriteLine("Groups: " + grouping.Count()); // returns 2!!!
        Console.WriteLine("Equals: " + office1.Equals(office2)); // returns true
        Console.WriteLine("Hash 1: " + office1.GetHashCode()); // returns 2067935290
        Console.WriteLine("Hash 2: " + office2.GetHashCode()); // returns 2067935290

        IEqualityComparer cmp = EqualityComparer<Office>.Default;
        Console.WriteLine("Comparer: " + cmp.Equals(office1, office2)); // returns true
上市公司=新上市公司();
Office office1=新办公室();
office1.Id=1;
office1.Name=“Office”;
office1.Stuff=“Stuff”;
Office office2=新办公室();
office2.Id=1;
office2.Name=“Office”;
office2.Stuff=“Stuff”;
公司日期1=新公司();
日期1.办公室=办公室1;
date1.Name=“date1”;
公司日期2=新公司();
日期2.办公室=办公室2;
date2.Name=“日期2”;
公司。添加(日期1);
公司。添加(日期2);
IEnumerable分组=companys.GroupBy(x=>x.Office);
Console.WriteLine(“Groups:+grouping.Count());//返回2!!!
Console.WriteLine(“等于:”+office1.Equals(office2));//返回true
Console.WriteLine(“散列1:+office1.GetHashCode());//返回2067935290
Console.WriteLine(“散列2:+office2.GetHashCode());//返回2067935290
IEqualityComparer cmp=EqualityComparer.Default;
Console.WriteLine(“Comparer:+cmp.Equals(office1,office2));//返回true
您可以看到,每个公司都有不同的Office对象,但在我的应用程序逻辑中,这些对象被认为是相等的。因此,调用
office1.Equals(office2)
返回true,对象hashcodes是相等的,使用
EqualityComparer.Default
的函数
Equals
也返回true

现在的谜团是为什么调用GroupBy office返回两个组,即使办公室是“相等的”。文档说明使用了密钥的默认EqualityComparer()


感谢您的帮助~

默认比较器正在调用
Object.GetHashCode
IEquatable.Equals

这对您不起作用,因为您正在隐藏
GetHashCode()
成员,而不是覆盖它

您的
Equals
GetHashCode
方法应该更改:

public **override** bool Equals(object obj)
public **override** int GetHashCode()

Jan,您可以在继承的方法
GetHashCode
Equals
中设置修饰符
override
,然后计数组等于1。这是因为,在Office比较器中,默认情况下调用方法
Equal
,并调用
Office
类中包含的非方法
Equal
。正确,例如:

public class Office : IEquatable<Office>
{
    public String Name { get; set; }
    public int Id { get; set; }
    public String Stuff { get; set; }

    // Compare by values
    public override  bool Equals(object obj)
    {
        if (obj is Office)
        {
            Office cmp = (Office) obj;
            bool result = true;
            result &= cmp.Id == this.Id;
            result &= cmp.Name == this.Name;
            result &= cmp.Stuff == this.Stuff;
            return result;
        }
        else return false;
    }

    // Hashcode by values
    public override int  GetHashCode()
    {
        var obj = new { Id = this.Id, Name = this.Name, Stuff = this.Stuff };
        return obj.GetHashCode();
    }

    // IEquatable uses overriden Equals implementation
    bool IEquatable<Office>.Equals(Office other)
    {
        return this.Equals(other);
    }
}
公共类办公室:IEquatable
{
公共字符串名称{get;set;}
公共int Id{get;set;}
公共字符串填充{get;set;}
//按值比较
公共覆盖布尔等于(对象对象对象)
{
如果(obj是办公室)
{
办公室cmp=(办公室)obj;
布尔结果=真;
result&=cmp.Id==this.Id;
result&=cmp.Name==this.Name;
result&=cmp.Stuff==this.Stuff;
返回结果;
}
否则返回false;
}
//哈希值编码
公共覆盖int GetHashCode()
{
var obj=new{Id=this.Id,Name=this.Name,Stuff=this.Stuff};
返回obj.GetHashCode();
}
//IEquatable使用覆盖的Equals实现
bool IEquatable.Equals(其他办公室)
{
返回此。等于(其他);
}
}

您必须正确重写
GetHashCode()
方法。您可能也不需要按位
&=
运算符,只需使用&&组合布尔值,这样可能会缩短计算过程。我不明白“正确”一词是什么意思。类
Office
重写此函数,并且
office1
office2
的哈希代码相等。匿名类型上的
GetHashCode
将哈希并合并其所有成员。很好,伙计们。对于超负荷的
GroupBy
(来自MSDN)
,默认的相等比较器默认值用于比较键。
Bingo。非常感谢。添加
override
关键字修复了问题。建议的方法只是覆盖相等成员
I可满足
在这种情况下没有任何交易。@Hamlet我不知道你的意思
EqualityComparer.Default
将使用
IEquatable.Equals
覆盖
Object.Equals
(如果可用)。我的意思是,如果您已覆盖类的equality成员,则无需实现
IEquatable
。在
IEquatable.Equals
和overrided
Equals
中有不同的行为已经注定了。明白了。在大多数情况下,唯一的区别应该是性能。