Это не должно быть медленно, если ваши сравнения не медленные.
Сканирование 500 объектов должно быть очень быстрым (конечно, вы не упоминаете, что такое «медленный», или ваш жесткий, но даже все же ...).
Ваш PassFilterVal будет "более дорогим" из-за вызова метода, чем сравнения в строке, но, поскольку он одинаков для всех них, я думаю, мы застряли с тем, что имеем.
Вы можете заказать параметры так, чтобы самые селективные были первыми.
Целью здесь является использование короткого замыкания AND для сброса как можно быстрее, тем самым ограничивая количество фактических сравнений.
Еще одна вещь, которую вы можете сделать, - это сначала оптимизировать ее для «самых распространенных запросов».
Всегда ли используются ВСЕ критерии? Если нет, вам следует ограничить сравнение теми, которые фактически используются. Равенство в этом случае действительно дорого (17 вызовов метода и 17 сравнений «неизвестной» сложности). Если у вас есть какой-то подстановочный знак или значение «не волнует», вы можете попытаться вообще его пропустить.
Другая идея состоит в сортировке элементов по всем 17 критериям. Затем вы используете бинарный поиск для элемента, который соответствует всем 17 полям, и, наконец, выполняете итерации для остальных элементов, пока они не перестанут соответствовать вашим критериям. Конечно, вы всегда должны правильно сортировать список, но после сортировки это будет двоичная вставка, которая будет довольно быстрой. Если вы читаете намного больше, чем добавляете в список, это должен быть чистый выигрыш.