2012-02-15 26 views
5

Tôi có 2 IList<T> cùng loại đối tượng ItemsDTO. Tôi muốn loại trừ một danh sách khỏi danh sách khác. Tuy nhiên điều này dường như không được làm việc cho tôi và tôi đã tự hỏi tại sao?LINQ Ngoại trừ() Phương thức không hoạt động

IList<ItemsDTO> related = itemsbl.GetRelatedItems(); 
IList<ItemsDTO> relating = itemsbl.GetRelatingItems().Except(related).ToList(); 

Tôi đang cố gắng để loại bỏ các mục trong related từ danh sách relating.

Trả lời

11

Vì lớp là loại tham chiếu, lớp ItemsDTO của bạn phải ghi đè EqualsGetHashCode để làm việc đó.

+0

Tôi nghĩ rằng sẽ đủ để ghi đè Chỉ bằng một mình. Tại sao bạn nghĩ rằng bạn cần phải ghi đè GetHashCode? – gprasant

+2

@gprasant http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c – Yuck

+2

'Ngoại trừ' sử dụng' HashSets' trong nội bộ. – Magnus

1

Từ MSDN:

Tạo sự khác biệt tập hợp của hai chuỗi bằng cách sử dụng sự bình đẳng Comparer mặc định để so sánh giá trị.

so sánh bình đẳng mặc định sẽ là so sánh tham chiếu. Vì vậy, nếu những danh sách đó được điền độc lập với nhau, chúng có thể chứa cùng các đối tượng từ quan điểm của bạn nhưng khác nhau tham chiếu .

Khi bạn sử dụng LINQ với SQL Server, bạn có lợi khi LINQ dịch câu lệnh LINQ của bạn thành truy vấn SQL có thể thực hiện bình đẳng logic cho bạn dựa trên khóa chính hoặc giá trị so sánh. Với LINQ to Objects, bạn cần phải xác định những gì logic bình đẳng có nghĩa là ItemsDTO. Và điều đó có nghĩa là ghi đè Equals() cũng như GetHashCode().

+0

+1 cho trường hợp đặc biệt khi bạn đang sử dụng LINQ2Sql – Magnus

0

Ngoại trừ hoạt động tốt cho các loại giá trị. Tuy nhiên, vì bạn đang sử dụng các loại Ref, bạn cần ghi đè EqualsGethashCode trên số ItemsDTO của mình để làm việc này

0

Tôi vừa gặp phải vấn đề tương tự. Rõ ràng NET nghĩ rằng các mục trong một danh sách khác với các mục tương tự trong danh sách khác (mặc dù chúng thực sự giống nhau). Đây là những gì tôi đã làm để sửa chữa:

Để lớp của bạn được kế thừa IEqualityComparer<T>, ví dụ:

public class ItemsDTO: IEqualityComparer<ItemsDTO> 
{ 
    public bool Equals(ItemsDTO x, ItemsDTO y) 
    { 
    if (x == null || y == null) return false; 

    return ReferenceEquals(x, y) || (x.Id == y.Id); // In this example, treat the items as equal if they have the same Id 
    } 

    public int GetHashCode(ItemsDTO obj) 
    { 
    return this.Id.GetHashCode(); 
    } 
} 
Các vấn đề liên quan