Làm cách nào để lọc ra các đối tượng dựa trên loại có nguồn gốc của chúng với các đối tượng LINQ?Loại trừ các loại biểu mẫu IEnumerable với linq
Tôi đang tìm giải pháp có hiệu suất tốt nhất.
Các lớp sử dụng:
abstract class Animal { }
class Dog : Animal { }
class Cat : Animal { }
class Duck : Animal { }
class MadDuck : Duck { }
tôi biết ba phương pháp: Sử dụng các từ khóa is
, sử dụng phương pháp Except
, và sử dụng các phương pháp OfType
.
List<Animal> animals = new List<Animal>
{
new Cat(),
new Dog(),
new Duck(),
new MadDuck(),
};
// Get all animals except ducks (and or their derived types)
var a = animals.Where(animal => (animal is Duck == false));
var b = animals.Except((IEnumerable<Animal>)animals.OfType<Duck>());
// Other suggestions
var c = animals.Where(animal => animal.GetType() != typeof(Duck))
// Accepted solution
var d = animals.Where(animal => !(animal is Duck));
Điều gì sẽ xảy ra nếu bạn có 'MadDuck', được thừa kế từ 'Vịt'? Có nên trả lại hay không? Và, btw, bạn đang cố gắng đạt được điều gì? Sử dụng 'is' và kiểm tra kiểu thời gian chạy có thể chỉ ra các vấn đề thiết kế. – Groo
Câu hỏi hay. Trong trường hợp cụ thể này, tôi cũng muốn các lớp con của Vịt được loại trừ. Điều đó sẽ làm cho tùy chọn của tôi 'b' không hợp lệ khi chúng so sánh loại nhưng không phải là thừa kế. – Aphelion
Về nhiệm vụ thứ hai của tôi: từ quan điểm của OOP, các phần khác của mã của bạn thường không nên quan tâm đến các loại đối tượng thực tế của bạn. Nên biết "càng ít càng tốt". Đó là lý do tại sao tôi tự hỏi tại sao bạn đang làm điều này. – Groo