0

I have the below code snippet in my project. I am new to lambda expressions. I have some idea about it and also started using it. But I do not understand how the below code is working. Specially,

NotifyIntrenal( notification, callback, changedTypes => ..

Now here changedTypes is one of the parameter for method NotifyIntrenal. We derive its value using an anomymous method.

If I see the code, since I do not assign any value to changedTypes, so as per my understanding the code if (changedTypes == null) should always be true. But this is not the case when I debug.

Can someone explain me how does this works here?

private void Notify( Notification notification )
{
    var nameDto = GetNameDto();
    foreach (var subscription in _subscriptionsDictionary)
    {
        var callback = subscription.Key;
        var subscribedTypes = subscription.Value;
        NotifyIntrenal( notification, callback, changedTypes =>
            {
                if (changedTypes == null)
                    return subscribedTypes;

                if (!changedTypes.Any())
                    return subscribedTypes;

                return changedTypes.Intersect(subscribedTypes);
             }, nameDto);
    }
}

Thanks & Regards

René Vogt
  • 43,056
  • 14
  • 77
  • 99
App
  • 346
  • 3
  • 9
  • A lambda expression is a *function*, `changedType` is the argument supplied by the caller (presumably within `NotifyIntrenal`). See [this possible duplicate](http://stackoverflow.com/questions/167343/c-sharp-lambda-expressions-why-should-i-use-them). – Charles Mager Aug 04 '16 at 12:05
  • 2
    Add the code of NotifyIntrenal – Steve Aug 04 '16 at 12:05
  • I understand what is happening with the above lambda, but is there really any benefit of not just putting that same code in a method? If nothing else it just seems like it would make the code cleaner. Or for that matter, the NotifyInternal() function could have that same logic inside it. Is there any performance advantage of doing it this way? – jpaugh78 Aug 04 '16 at 12:26
  • No, there is no performance-impact. You could of course also implement that logic within `NotifyIntrenal`. The question is: do you call `NotifyIntrenal` from another context also where you want to do something different? Than you have to provide this "what to do now" by a `Func` (or alternativly via an `Action`). – MakePeaceGreatAgain Aug 04 '16 at 12:29
  • @HimBromBeere That makes sense. I'm still trying to learn Lambda's and anonymous methods, thanks for the reply. – jpaugh78 Aug 04 '16 at 13:23

2 Answers2

3

changedTypes is not an argument to NotifyInternal. It is the parameter for the anonymous method.
This whole method is the argument for NotifyInternal.

The code inside that lambda is not executed at this point. It will only be executed if some line in NotifyInternal calls it. So there has to be code line in NotifyInternal executing the anonymous method:

void NotifyInternal(Notification notification, Callback callback, Func<IEnumerable<Type>, IEnumerable<Type>> function, string nameDto)
{
    // ... some code

    // execute the lambda
    var result = function(mychangedtypesvariable);

    // ... more code
}

Only then the code inside the lambda is executed, using the pass argument (mychangedtypesvariable in that example). So if this will be null you cannot decide from the snippet you see.

René Vogt
  • 43,056
  • 14
  • 77
  • 99
0

changedTypes is just a paremeter for your anonymous method, not for NotifyIntrenal. The latter however calls that anonymous method and fills the parameter (if required) appropriately. In your case the anonymous method expects an IEnumerable<MyType> and returns an IEnumerable<MyType>.

NotifyIntrenal(string arg1, string arg2, Func<IEnumerable<MyType>, IEnumerable<MyType>> func) {
    // do something

    var list = new List<MyType> { ...}
    // execute the delegate with the list
    IEnumerable<MyType> result = func(list);
}

So actually changedTypes is provided by NotifyIntrenal, not given to it. How you create that argument within the method is up to you.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111