对IEnumerable.GroupBy()中使用的类型有什么要求?

时间:2016-05-18 11:45:57

标签: c# linq

我使用GroupBy匿名类型:

var v = list.GroupBy(x => new {x.street, x.houseNumber});
var o = v.Single(x => x.Key.street == "My Street" && x.Key.houseNumber == 42);

效果很好。我决定将其变成具体类型:

class StreetAddress
{
 public StreetAddress(string _street,int _houseNumber){...}
 public string street{get; set;}
 public int houseNumber{get;set;}
}
var v = list.GroupBy(x => new StreetAddress(x.street, x.houseNumber));
var o = v.Single(x => x.Key == new StreetAddress("My Street", 42));

现在'v'根本没有分组 - 具有相同Key值的项目加载,而o与任何对象都不匹配。

我需要将哪些内容添加到StreetAddress,这样可以像使用匿名类型一样工作?

2 个答案:

答案 0 :(得分:7)

  

我需要添加什么来添加到StreetAddress,这样可以像使用匿名类型一样工作?

基本上覆盖EqualsGetHashCode。理想情况下,实施IEquatable<StreetAddress>,但主要是为了清晰起见。

您当前的查询按类型表达的唯一相等类型进行分组 - 引用相等。但是,当您为每个项目创建一个新实例时,没有两个键会彼此相等。

答案 1 :(得分:-2)

以下是如何实现IComparable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication93
{
    class Program
    {
        static void Main(string[] args)
        {
            var v = StreetAddress.addresses.GroupBy(x => x);
        }
    }
    class StreetAddress : IComparable
    {
        public static List<StreetAddress> addresses { get; set; }
        public string street { get; set; }
        public int houseNumber { get; set; }

        public StreetAddress() { ; }
        public StreetAddress(string _street, int _houseNumber)
        {
            StreetAddress newAddress = new StreetAddress();
            addresses.Add(newAddress);
            newAddress.street = _street;
            newAddress.houseNumber = _houseNumber;
        }
        public int CompareTo(object _other)
        {
            int results = 0;
            StreetAddress other = (StreetAddress)_other;
            if (this.street != other.street)
            {
                results = this.street.CompareTo(other.street);
            }
            else
            {
                results = this.houseNumber.CompareTo(other.houseNumber);
            }

            return results;
        }

    }


}