24

I have a method for getting values from database.

 public virtual List<TEntity> GetValues(
           int? parameter1 = null,
           int? parameter2 = null,
           int? parameter3 = null,
           params Expression<Func<TEntity, object>>[] include)
        {
            //...
        } 

How can I call this function with named parameter to not write all parameters before include? I want to do something like this

var userInfo1 = Unit.UserSrvc.GetValues(include: p => p.Membership, p => p.User);

But this doesn't seem working? How can I use named parameter with params?

Chuck Norris
  • 15,207
  • 15
  • 92
  • 123
  • 2
    found this question on an msdn thread - looks like you'd have to name every argument in the params list or something? http://bit.ly/GPZvkH – james lewis Mar 26 '12 at 12:30
  • Thanks James. By the way, answer isn't found yet... I think it's not implemented in .NET yet. – Chuck Norris Mar 26 '12 at 12:39
  • @ChuckNorris, this has nothing to do with .Net, only with C#. Other .Net languages can handle `params` and named parameters differently, so what you want might be already possible in some other language. Also, I think there is no “yet”: this is unlikely to change in future versions of C#. – svick Mar 26 '12 at 12:46
  • Thanks for the answer @svick. I think it's not too hard to implement this future. It can be implemented by naming only first element of params array. Compiler should understand only that if after named argument there are still other argument, they are part of params parameter. – Chuck Norris Mar 26 '12 at 12:49
  • @ChuckNorris, I'm not saying it would be hard to implement. I'm saying it was a deliberate choice not to do it this way, and that's why its' not likely to change. The problem with your syntax is that it already has a well-defined meaning: call the method the first parameter `p => p.User` and the `params` array containing one element `p => p.Memebership`. Just because in your case that won't compile because of type mismatch, doesn't mean it won't work correctly in other cases. – svick Mar 26 '12 at 12:57

2 Answers2

12

I think the only way is something like:

GetValues(include:
   new Expression<Func<TEntity, object>>[] { p => p.Membership, p => p.User })

Which is not that great. It would be probably best if you added an overload for that:

public List<Entity> GetValues(params Expression<Func<Entity, object>>[] include)
{
    return GetValues(null, null, null, include);
}

Then you call your method just like

GetValues(p => p.Membership, p => p.User)
svick
  • 236,525
  • 50
  • 385
  • 514
  • Agree with @svick - u should probably add a couple of overloads for your typical usage scenarios. – VinayC Mar 26 '12 at 12:40
8

A params argument works like an array, try this syntax:

var userInfo1 = Unit.UserSrvc.GetValues(include: new Expression<Func<TEntity, object>>[] { p => p.Membership, p => p.User });

(Might need some adapting due to the generic parameter, but I think you get the gist of it)

madd0
  • 9,053
  • 3
  • 35
  • 62
  • 5
    If you do it this way, there is no point having the `params` keyword specified. This is no different to just having a plain array as the last argument. The OP is asking how to do it with `params`. – Rob Levine Mar 26 '12 at 12:21
  • 1
    Thanks for the answer, but it isn't what I want exactly... Rob Levine is right, but seems no way to do this with params. – Chuck Norris Mar 26 '12 at 12:24
  • Oh, I see, I misunderstood what you needed. Writing overloads is the only alternative I see, but again, that's not what you want... – madd0 Mar 26 '12 at 12:29
  • 1
    @RobLevine `This is no different to just having a plain array as the last argument` Not quite, you don't have to specify the array if you're only calling it with a single argument. – MrLore Nov 10 '15 at 17:06