7

I'm writing a method and depending on a config field I need to change where I get my data from. What this results in me having to write code that looks like this:

List<string> result = new List<string>();
if (configField)
{
    result.Add(fieldA);
}
else
{
    result.Add(...BusinessLogic...);
}

I'll have to write that if statement many many times so of course I want to turn it into a method instead so I can just write result.Add(newMethod(configField, fieldA, dataForBusinessLogicToParse)). This method would be useless to anyone not writing the specific method I'm writing so does it make sense to declare this method as a separate private method or can I just declare it inline as a delegate like this:

Func<Enum, int, int> newMethod =
    (configField, fieldA, dataForBusinessLogicToParse) => ...businessLogic...

I'm worried declaring it inline might make the code more difficult to understand but I think it makes the class cleaner.

5
  • 1
    Depends on who you ask I guess. This sort of thing is pretty common in functional programming, but it'd be foreign to a Java-less-than-8 developer. – Doval Jul 8 '14 at 15:31
  • 1
    I think "inline" is the wrong terminus here (see en.wikipedia.org/wiki/Inlining). I guess you mean "nested". – Stefan Falk Jul 8 '14 at 15:43
  • I like this kind of coding. Others don't, but I strongly disagree with them. C# supports it, it makes the code way simpler without creating functions that no-one else needs to know about and allows reducing the number of function parameters by utilizing local parameter closure. So this is using C# the best way you can to achieve what you want. I don't think there should even be good practices for that kind of stuff... – user2173353 Nov 2 '16 at 14:31
  • @user2173353 "functions that no-one else needs to know about" you mean private functions? – R. Schmitz Aug 15 '18 at 9:25
  • @R.Schmitz Yes, private, but not on the class level. I mean things like the example in the question, when declared inside a function/method. Now C# supports a better syntax as well. There are some things that not even the other class members should know about. Not to mention that you can capture local variables using that way too, making the code less complex and more readable. – user2173353 Aug 21 '18 at 6:19
4

As far as I know, declaring a helper method as a lambda like this is not commonly done in C#, so I would advise against doing this unless you have a good reason.

Good reasons include:

  • The lambda could do something a separate method can't, like closing over a local variable or using anonymous type.
  • Others in your team agree with you that this is a good practice.

That being said, starting with C# 7.0, C# supports local functions, which are similar to such helper lambdas, but generally better: they have more succinct syntax and are more efficient. So if you used a local function for this purpose, I think that would be perfectly fine.

2
  • This answer's emphasis on popularity bothers me a bit. That said, I think this style is probably a bit more "popular" nowadays than it used to be when you wrote this answer, because it allows very short bits of method functionality without requiring the bracing ceremony. A couple of years ago, I made use of this technique to build a rules engine, encoding the rules in lambda/expression trees that could be visited for logging purposes. – Robert Harvey Aug 14 '18 at 15:11
  • @RobertHarvey I do think this answer is outdated, but for a different reason: local functions. I have updated the answer. – svick Aug 14 '18 at 19:10
6

If newMethod never changes its value after initialization (it could be declared const or readonly, I guess), you should better write a standard private method. Using delegates without a reason can make the code confusing (at least in C#), even for experienced programmers. Comparing

 private Action<Enum, int, int> newMethod = (configField, fieldA, dataForBusinessLogicToParse) ...

vs.

 private void NewMethod(Enum  configField, int fieldA, int dataForBusinessLogicToParse)
 {
 }

the latter is much more readable for me, because I see immediately which parameter has which type, whilst for the first construct I have to count parameters (especially when the number of parameters becomes more than 3).

1
  • 1
    I think newMethod was supposed to be a local variable (hence “inline”), not a field. – svick Jul 16 '14 at 13:17
4

Since C# 7, it supports inner functions. These combine the locality and closure benefits of lambdas with the nicer (for non-one-liners) syntax of functions. You have the option to use those.

Not the answer you're looking for? Browse other questions tagged or ask your own question.