Я использовал LINQ с скомпилированными запросами, в основном переходя в скомпилированный запрос с помощью Func, но проблема в том, что он имеет максимум четыре параметра.

Это хорошая практика - продлевать это?

Есть ли способ расширить это или я должен создать своего собственного делегата?

Иногда мне нужно передать шесть параметров, а другим - пять, а другим - четыре или меньше ... поэтому с четырьмя или меньше я мог бы продолжить использование делегата Func.

В настоящее время передача в контексте данных и сочетание необходимых мне параметров зависят от каждого отдельного скомпилированного запроса.

2
mark smith 9 Ноя 2009 в 13:01
@ Митч: Можете ли вы помочь мне с моим (все, что старше 50, не является концом света в моей книге): D
 – 
Ruben Bartelink
9 Ноя 2009 в 13:07
1
Я согласен с Рубеном - было бы разумнее ввести новый класс для переноса всех этих параметров (возможно, вы даже захотите использовать интерфейс, чтобы ослабить связь). Другими словами, вы закончите чем-то вроде Func<IMyData>, где IMyData содержит набор (только для чтения) свойств.
 – 
Groo
9 Ноя 2009 в 13:41

2 ответа

Лучший ответ

Просто объявите своих собственных делегатов - для этого достаточно одной строчки кода. См. мои примеры объявления делегатов .NET 3.5 в .NET 2.0 для своего рода шаблона. , если вам это нужно.

Я не знаю, насколько хорошо это будет работать с скомпилированными запросами LINQ - надеюсь, это не будет проблемой, но ваш вариант использования не совсем ясен, чтобы я мог сказать наверняка.

Обратите внимание, что в .NET 4.0 есть поддержка Func. / Действие с максимум 8 параметрами.

5
Jon Skeet 9 Ноя 2009 в 13:06
Спасибо, Джон, поэтому я предполагаю, что если .net 4.0 будет иметь до 8 параметров, это не лучшая идея для создания моего собственного Func с 5 параметрами .. Я должен назвать его как-нибудь иначе ИЛИ ПО МИНИМУМУ поместить его в собственное пространство имен?
 – 
mark smith
9 Ноя 2009 в 14:20
@mark: Это зависит от того, что вы создаете, и от того, как вы планируете подходить к .NET 4.0. Если это библиотека, которая должна работать с разными версиями .NET, это сложно. Если это приложение, которое вы можете «обновить» один раз, удалив объявления делегатов, это проще.
 – 
Jon Skeet
9 Ноя 2009 в 14:27
Спасибо, Джон, вот что я сделаю, просто удалю делегата, когда появится .net 4.0.
 – 
mark smith
9 Ноя 2009 в 15:37
Джон, у меня 1 вопрос - возможно, вы подтвердите, новый делегат работает, но мне нужно передать его в CompileQuery of LINQ ... и он поддерживает только до 4 ... Я просмотрел код с отражателем, но кажется, что, возможно, лучший способ - передать параметры в объекте параметра согласно предложению Рубена. Но это означает, что мне придется создавать новый объект параметра для каждого набора параметров? Вы знаете способ получше?
 – 
mark smith
9 Ноя 2009 в 16:08
Не совсем - если вам нужно передать его в LINQ to SQL, вам придется использовать тип делегата, который понимает LINQ to SQL.
 – 
Jon Skeet
9 Ноя 2009 в 16:16

То, что сказал Джон, плюс ...

Как вы и предположили, обычно у вас не должно получаться слишком много параметров - обычно вы должны обнаружить, что какая-то объединяющая концепция выскакивает, сообщая вам Добавить объект параметра. Сказав это, 4 не было бы тем местом, где я бы поместил строчку «это просто безумие».

2
Groo 9 Ноя 2009 в 13:35
Спасибо, Рубен, за ваш комментарий, я сохраню его на будущее! В настоящее время мне нужно максимум 6, я думаю, так что я думаю, что это вполне выполнимо
 – 
mark smith
9 Ноя 2009 в 14:27
Привет, Рубен, я думаю об использовании твоей техники, но в этом примере он создает объект параметра с типами, например, int, string и т.д. передавая внутрь всевозможные типы. Я мог бы просто указать его как объект, я полагаю, но тогда мне нужно будет преобразовать его в фактический тип?
 – 
mark smith
9 Ноя 2009 в 16:10
Привет, Марк! Ссылка на образец паттерна была вставлена ​​редактором (спасибо, Groo!). Если вы хотите использовать предопределенный класс, это больше похоже на Tuples (которые есть в F # и .NET 4). Основная идея IPO заключается в том, что вы должны создать новый класс с хорошим именем, которое представляет общую концепцию набора передаваемых вами частей, например, вместо «заголовок, тело, трейлер» у вас есть DocumentDefinition со свойствами или методами, завершающими его. Ничто не мешает вам использовать словарь как сумку для их передачи, но это будет другой подход.
 – 
Ruben Bartelink
9 Ноя 2009 в 16:54
Для получения информации о кортежах (как и Twitter, SO считает буквы URL-адреса настоящими!) См. blogs.msdn.com/bclteam/archive/2009/07/07/…
 – 
Ruben Bartelink
9 Ноя 2009 в 16:55
Просто читаю ваш разговор с Лошадью ... Это может или не может быть применимо к вашему контексту - это просто общий рефакторинг, который применяется, когда вы обнаруживаете, что передаете множество параметров, которые являются классом, ожидающим идентификации.
 – 
Ruben Bartelink
9 Ноя 2009 в 16:58