views:

507

answers:

2

I have been using LINQ with compiled queries, basically passing into the compiled query using Func but the problem is that it has a maximum of four parameters.

Is it good practice to extend this?

Is there any way to extend this or should I create my own delegate?

Sometimes I need to pass six params and others five and others four or less... so with four or less I could continue using the Func delegate.

Currently passing in data context and a mix of the params I need are dependent on each individual compiled query.

+3  A: 

Just declare your own delegates - it's only a single line of code to do so. See my examples for declaring the .NET 3.5 delegates in .NET 2.0 for a sort of template, if you need it.

I don't know how well this will work with LINQ compiled queries - hopefully it won't be a problem, but your use case isn't quite clear enough to me to say for sure.

Note that in .NET 4.0 there's support for Func/Action with up to 8 parameters.

Jon Skeet
Thanks jon, so i presume if .net 4.0 is going to have up to 8 params its not a good idea to create my own Func with 5 params.. i should name it something else OR AT LEAST put it in its own namespace?
mark smith
@mark: It depends on what you're building, and how you're planning to approach .NET 4.0. If it's a library which should work with different versions of .NET, that's tricky. If it's an application which you can "upgrade" once by removing your delegate declarations, that's simpler.
Jon Skeet
Thanks Jon, thats what i will do it just remove the delegate when .net 4.0 comes along
mark smith
Jon, i have 1 question - maybe you can confirm, the new delegate is working but i need to pass it into CompileQuery of LINQ .. and that only supports up to 4 as well... I have looked at the code with reflector but it seems maybe the best way would be to pass the parameters in a parameter Object as per Ruben's suggestion.. But this means i going to have to create a new parameter object for every different collection of parameters? Do you know of a better way?
mark smith
Not really - if you need to pass it into LINQ to SQL, you're going to have to use a delegate type that LINQ to SQL understands.
Jon Skeet
Agreed, so i am going to create a parameter class and pass it into the stanadard FUNC and then into CompiledQuery ... Thank you for conifrming this!! - i learn something new every day!!!
mark smith
+2  A: 

What Jon said plus...

As you've suggested, generally you shouldnt end up with too many params - generally you should find some uniting concept jumping out telling you to Introduce Parameter Object. Having said that, 4 wouldnt be the place where I'd place a 'that's just crazy' line.

Ruben Bartelink
Thanks Ruben for your comment, i will keep this for the future! Currently i need only a max of 6 i think - so i think its quite manageable
mark smith
Hi Ruben, i am thinking of using your technique but in the example it creates a parameter object with types i.e. int,string etc etc.. Do you know if its possible to use a kind of generic version so that i can use this object for passing all different types inside. I could just specify it as Object i suppose but then i will need to Cast to the actual type?
mark smith
Hi Mark, The reference to the example of the pattern was inserted by an editor (Thanks Groo!). If you're looking to use a predefined class, that's more like Tuples (which are in F# and .NET 4). The main point of IPO is that that you'd create a new class with a good name which represents the overall concept behind the set of partams you're passing, e.g., instead of "header, body, trailer" you have a `DocumentDefinition` with properties or methods wrapping it up. There's nothing stopping you using a Dictionary as a Bag to pass them as, but that would be a differnt approach.
Ruben Bartelink
For info on tuples (Like Twitter, SO counts the letters of a URL as real letters!), see http://blogs.msdn.com/bclteam/archive/2009/07/07/building-tuple-matt-ellis.aspx
Ruben Bartelink
Just reading your conversation w/ The Horse... This may or may not be applicable to your context - its just a general refactoring that applies when you're find yourself passing lots of parameters that are a class waiting to be identified.
Ruben Bartelink
thanks, i have managed to get something going...thanks for your comments
mark smith