class Program
{
static void Main(string[] args)
{
List<Book> books = new List<Book>
{
new Book
{
Name="C# in Depth",
Authors = new List<Author>
{
new Author
{
FirstName = "Jon", LastName="Skeet"
},
new Author
{
FirstName = "Jon", LastName="Skeet"
},
}
},
new Book
{
Name="LINQ in Action",
Authors = new List<Author>
{
new Author
{
FirstName = "Fabrice", LastName="Marguerie"
},
new Author
{
FirstName = "Steve", LastName="Eichert"
},
new Author
{
FirstName = "Jim", LastName="Wooley"
},
}
},
};
var temp = books.SelectMany(book => book.Authors).Distinct();
foreach (var author in temp)
{
Console.WriteLine(author.FirstName + " " + author.LastName);
}
Console.Read();
}
}
public class Book
{
public string Name { get; set; }
public List<Author> Authors { get; set; }
}
public class Author
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override bool Equals(object obj)
{
return true;
//if (obj.GetType() != typeof(Author)) return false;
//else return ((Author)obj).FirstName == this.FirstName && ((Author)obj).FirstName == this.LastName;
}
}
Questo è basato su un esempio in "LINQ in azione". Listato 4.16.Distinto non funziona con LINQ to Objects
Questo stampa due volte Jon Skeet. Perché? Ho persino provato a sovrascrivere il metodo Equals nella classe Author. Still Distinct non sembra funzionare. Cosa mi manca?
Modifica: Ho aggiunto anche il sovraccarico dell'operatore == e! =. Ancora nessun aiuto.
public static bool operator ==(Author a, Author b)
{
return true;
}
public static bool operator !=(Author a, Author b)
{
return false;
}
IEquatable è soddisfacente ma incompleto; dovresti * sempre * implementare Object.Equals() e Object.GetHashCode() insieme; IEquatable. Equals non esegue l'override di Object.Equals, quindi non riuscirà quando si effettuano confronti non fortemente tipizzati, che si verificano spesso nei framework e sempre in raccolte non generiche. –
AndyM
Quindi è meglio usare l'override di Distinct che prende IEqualityComparer come suggerito da Rex M? Intendo cosa dovrei fare se non voglio cadere nella trappola. –
Tanmoy
@Tanmoy dipende. Se vuoi che l'autore si comporti normalmente come un oggetto normale (vale a dire solo l'uguaglianza di riferimento) ma controlli i valori del nome per lo scopo di Distinct, usa unCompetitore IEquality. Se * sempre * vuoi che gli oggetti Autore siano confrontati in base ai valori del nome, allora sostituisci GetHashCode ed Equals oppure implementa IEquatable. –