开发者

When is it too much "lambda action"?

开发者 https://www.devze.com 2022-12-11 00:39 出处:网络
I often find myself using lambdas as some sort of \"local functions\" to make my life easier with repetetive operations like those:

I often find myself using lambdas as some sort of "local functions" to make my life easier with repetetive operations like those:

Func<string, string> GetText = (resource) => this.resourceManager.GetString(resource);
Func<float, object, string> FormatF1 = (f, o) => String.Format("{0:F1} {1}", f, o);
Func<float, object, string> FormatF2 = (f, o) => String.Format("{0:F2} {1}", f, o);

Instead of writing the String.Format-thing over and over, I can happily blow away with FormatF2 e.g. and save myself time and when I need to change something about the formatting, only one place to make edits. Especially when I need the functionality in the given function exclusively, I'm very reluctant to turn them into a real function. While the lambdas above were relatively small... sometimes I have larger ones like (the following is supposed to add data to a table for print output):

Action<string, string, string> AddSurfaceData = (resource, col, unit) => {
    renderTable.Cells[tableRowIndex, 0].Text = "\t" + this.GetText(resource);
    renderTable.Cells[tableRowIndex, 1].Text = FormatF2(paraHydReader.GetFloat(paraHydReader.GetOrdinal(col)), "");
    renderTable.Cells[tableRowIndex, 1].Style.TextAlignHorz = C1.C1Preview.AlignHorzEnum.Right;
    renderTable.Cells[tableRowIndex, 2].Text = " " + this.GetText(unit);
    renderTable.Cells[tableRowIndex, 2].Style.Tex开发者_如何学运维tAlignHorz = C1.C1Preview.AlignHorzEnum.Left;
    ++tableRowIndex;
};

Again, I need this often and all the benefits of above apply, too. However, as you can see, this one is quite long for a lambda expression.. the question is: When do you draw the line? Is my last lambda too much? What other ways (other than using real functions or trying to stuff the data in containers and loop over them) exist to avoid writing the same code over and over again?

Thanks in advance

Christian


It is something you use potentially many times within a method, and only that inside that method. I like this idea. Do it if it doesn't make your code hard to read. I would say that you should reconsider if you find it difficult to see what is the content of the lambda function vs. what is the real content of the method. In that case it might be cleaner to pull it out in a separate private method.

At the end, this is really a matter of taste...


I agree with awe: for small scale reuse inside a method (or even a class) this is perfect. Like the string.Format examples. I use this quite often. It's basically the same thing as using a local variable for an intermediate value that you use more than once, but then for code.

Your second example seems to be pushing it a bit. Somehow this gives me the feeling a private method AddSurfaceData (possibly static, depending on its use?) would be a better fit. That is of course outside of the context that you have, so use your own good judgement.


A Lambda method is an anonymous method.

This means that you should not give it a name.

If you are doing that, (in your case, you are assigning a name with your reference), it's just another way to declare a function.

C# has already got a way to declare functions, and it's not the lambda way, which was added uniquely to pass functions via parameters and returns them as return values.

Think, as an example, in javascript:

function f(var1,var2,...,varX)
{
    some code
}

or

var f = function() {
    some code    
}

Different syntax (almost) same thing.

For more information on why it's not the same thing: Javascript: var functionName = function() {} vs function functionName() {}

Another example: in Haskell You can define two functions:

 function1 :: Int -> Int
 function1 x = x + 2

or

 function2 :: Int -> Int
 function2 = \x -> x + 2

Same thing (this time I think it's the very same), different syntax. I prefer the first one, it's more clear.

C# 3.5, as Javascript, has got a lot of functional influences. Some of them should it be used wisely, IMHO.

Someone said local lambda functions with assignment in a reference is a good substitute for a method defined within another method, similar to a "let", or a "where" clause in Haskell.

I say "similar" because the twos have very different semantics, for instance, in Haskell I can use function name which is not declared yet and define it later with "where", while in C#, with function/reference assignment I can't do this.

By the way I think it's a good idea, I'm not banning this use of lambda function, I just want to make people think about it. Every language has got his abstraction mechanism, use it wisely.


I like the idea. I don't see a better way to maintain code locality without violating the DRY principle. And I think it's only harder to read if you're not accustomed to lambdas.


+1 on nikie re DRY being good in general.

I wouldnt use PascalCase naming for them though.

Be careful though - in most cases the stuff you have in there is just an Extract Method in a dress or a potential helper or extension function. e.g., GetText is a Method and FormatF* is probably a helper method...


I have no problem with the long example. I see that you are repackaging compound data very elegantly.

It's the short ones that will drive your colleagues to investigate the advantages of voluntary institutionalization. Please declare some kind of constant to hold your format string and use "that String.Format-thing over and over". As a C# programmer, I know what that does without looking elsewhere for home-spun functions. That way, when I need to know what the formatted string will look like, I can just examine the constant.


I agree with volothamp in general, but in addition ...

Think of the other people that have to maintain your code. I think this is easier to understand than your first example and still offers the maintenance benefits you mention:

String.Format(this.resourceManager.GetString("BasicFormat"), f, o);
String.Format(this.resourceManager.GetString("AdvancedFormat"), f, o);

And your second example appears to be just a different way to declare a function. I don't see any useful benefit over declaring a helper method. And declaring a helper method will be more understandable to the majority of coders.


I personally think its not in good taste to use lambda functions when there is no need for it. I personally wont use a lambda function to replace a simple few lines of procedural code. Lambda functions offer many enhancements, but make the code slightly more complicated to read.

I wouldnt use it to replace string.format.

0

精彩评论

暂无评论...
验证码 换一张
取 消