Dimas Longo
Dimas Longo

Reputation: 1217

trying to exclude elements from an IEnumerable structure using Except

I am trying to remove elements from an IEnumerable type from another IEnumerable.

Here I get the complete list

var tiposObj = from t in context.sistema_DocType
                               select
                                   new tgpwebged.Models.SettingsModels.TipoIndiceModel
                                   {
                                       id = t.id,
                                       tipo = t.tipoName
                                   };

                classificacaoModel.tipos = tiposObj.ToList();

And here a partial list to be excluded from the first

  var tiposAtribuidosObj = from t in context.sistema_DocType
                                        join c in context.sistema_ClassificacaoTipo on t.id equals c.idTipo
                                        where c.idClassificacao == classificacaoId
                                        select new tgpwebged.Models.SettingsModels.TipoIndiceModel
                                        {
                                            id = t.id,
                                            tipo = t.tipoName
                                        };
                classificacaoModel.tiposAtribuidos = tiposAtribuidosObj.ToList();   

Here is how I am excluding:

classificacaoModel.tiposNaoAtribuidos = classificacaoModel.tipos.Except(classificacaoModel.tiposAtribuidos);

No elements is excluded from the first list. Can´t figure out why. They have same structure and same types.

Upvotes: 1

Views: 839

Answers (2)

Tigran
Tigran

Reputation: 62248

.NET framework has no way to compare 2 instances of TipoIndiceModel. For this you have to implement IEqualityComparer or derive from EqualityComparer.

Hint from MSDN on Except:

This interface supports only equality comparisons. Customization of comparisons for sorting and ordering is provided by the IComparer generic interface.

We recommend that you derive from the EqualityComparer class instead of implementing the IEqualityComparer interface, because the EqualityComparer class tests for equality using the IEquatable.Equals method instead of the Object.Equals method. This is consistent with the Contains, IndexOf, LastIndexOf, and Remove methods of the Dictionary class and other generic collections.

Upvotes: 2

Jamiec
Jamiec

Reputation: 136074

They may be the same type, but they are not the same instance.

The solution is to override Equals on TipoIndiceModel to provide member equality rather than the default reference equality. Consider implementing IEquatable<TipoIndiceModel> too!

Reference:

IEquatable interface: http://msdn.microsoft.com/en-us/library/ms131187.aspx

If you implement IEquatable, you should also override the base class implementations of Object.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable.Equals method.

Guidelines for Overloading Equals() and Operator == http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx

Upvotes: 1

Related Questions