Mr. Boy
Mr. Boy

Reputation: 63758

What requirements on type used in IEnumerable.GroupBy()?

I was using GroupBy with an anonymous type:

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

It worked great. I decided to turn this into a concrete type:

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

Now 'v' is not grouped at all - loads of items with the same Key value, and o doesn't match any objects.

What do I need to add to StreetAddress so this works as it did with an anonymous type?

Upvotes: 2

Views: 130

Answers (2)

jdweng
jdweng

Reputation: 34429

Here is how to implement 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;
        }

    }


}

Upvotes: -2

Jon Skeet
Jon Skeet

Reputation: 1501656

What do I need to add to StreetAddress so this works as it did with an anonymous type?

Override Equals and GetHashCode, basically. Ideally, implement IEquatable<StreetAddress>, but mostly for the sake of clarity.

Your query currently is grouped by the only type of equality that the type expresses - referential equality. But as you're creating a new instance for each item, no two keys will ever be equal to each other.

Upvotes: 7

Related Questions