score:4

Accepted answer

Currently you run Distinct() on a collection of FamilySelector instances which results to comparing by reference equality.

To do it right, you should pass an instance of IEqualityComparer to Distinct() call:

var source = _mfgOrdersData
    .Select(o => new FamilySelector(o.ItemWrapper.ItemClass, o.ItemWrapper.Family))
    .Distinct(new FamilySelector())
    .OrderBy(f => f.CodeFamily)
    .ToList();

You should add parameterless constructor to FamilySelector class so that code could be compiled.

I'd also suggest small refactoring of FamilySelector class. Currently it holds the data and performs comparison. Usually implementation of IEqualityComparer is a data-less class that just performs a comparison:

class FamilyData
{
    public FamilyData(string code, string family)
    {
        Code = code;
        Family = family;
    }

    public string Code { get; set; }
    public string Family { get; set; }
    public string CodeFamily { get { return string.Format("{0}\t{1}", Code, Family); } }
}

class FamilySelector : IEqualityComparer<FamilyData>
{
    public bool Equals(FamilyData x, FamilyData y)
    {
        return x.Code == y.Code && x.Family == y.Family;
    }

    public int GetHashCode(FamilyData obj)
    {
        return obj.Code.GetHashCode() ^ obj.Family.GetHashCode();
    }
}

var source = _mfgOrdersData
    .Select(o => new FamilyData(o.ItemWrapper.ItemClass, o.ItemWrapper.Family))
    .Distinct(new FamilySelector())
    .OrderBy(f => f.CodeFamily)
    .ToList();

score:2

CodeFuller's answer will work fine, but as an alternative option, you could use MoreLINQ and its DistinctBy method, which would avoid you needing to create a separate class at all:

private void PopulateFamily()
{
    var source = _mfgOrdersData
        .Select(o => o.ItemWrapper)
        .DistinctBy(o => new { o.ItemClass, o.Family })
        .OrderBy(f => f.CodeFamily)
        .ToList();

    FamilyFilterListBox.DataSource = source;
    FamilyFilterListBox.ValueMember = "Family";
    FamilyFilterListBox.DisplayMember = "CodeFamily";
}

I've assumed that you want to select ItemWrapper - it's hard to tell without seeing the types involved, but that looks likely to be what you want.


Related Query

More Query from same tag