I have never programmed in C# so this is just my thinking.
I think lambda-functions and methods of an instance are different. One of them is bound to the specific object while the other one is an anonymous function which can be transfered anywhere. I believe you can't transfer the method of the specific instance.
Another idea would be, that forEach needs something defined which can be used for substitution in its iterations, while
hashCodeDelegate.Add
doesn't defined where should it be substituted.
The lambda-function clearly defines a variable which will be used like in a for loop for(str in sentence)
which will be just pasted in the code block hashCodeLambda.Add(str)
str => hashCodeLambda.Add(str)
And this is what claude.ai returns regarding the problem:
What could be clarified:
The main reason for the different behavior is method group conversion. hashCodeDelegate.Add is a method group that the compiler must convert to a delegate. In doing so, it "binds" the method to the current instance of hashCodeDelegate.
Both are actually "bound": Both str => hashCodeLambda.Add(str) and hashCodeDelegate.Add capture their respective instances. The difference lies in when this binding occurs.
More precise explanation: With hashCodeDelegate.Add, the same once-bound instance is always used at the time of ForEach execution. The lambda str => hashCodeLambda.Add(str), however, captures the variable hashCodeLambda and resolves it anew with each execution.
Suggestion for improving your answer: You could mention that this is about "method group conversion" vs. "lambda capture" - those would be the correct C# technical terms for this phenomenon.