Best lambda questions in May 2012

What is the scope of a lambda variable in C#?

51 votes

I'm confused about the scope of the lambda variable, take for instance the following

var query = 
    from customer in clist
    from order in olist
    .Where(o => o.CustomerID == customer.CustomerID && o.OrderDate ==  // line 1
        olist.Where(o1 => o1.CustomerID == customer.CustomerID)        // line 2
             .Max(o1 => o1.OrderDate)                                  // line 3
    )
    select new {
        customer.CustomerID,
        customer.Name,
        customer.Address,
        order.Product,
        order.OrderDate
    };

In line 1 I have declare a lambda variable 'o' which means I cannot declare it again in line 2 (or at least the compiler complains if I try to) But it doesn't complain about line 3 even though 'o1' already exists??

What is the scope of a lambda variable?

The brackets give the clue - the lambda variable is captured in the scope of where it's declared:

.Where(o => ... olist.Where(o1 => ...).Max(o1 => ...))
  //  |----------------------------------------------| scope of o
  //                       |---------|                 scope of first o1
  //                                      |---------|  scope of second o1

Note that there's no overlap for the two o1 variables, but they both overlap (or shadow) the o variable and hence can't use the same name.

Handling events with C# Extension Methods

6 votes

I recently learned about using C# extension methods to make calling events easier and I've been using them more and more. I recently hit a strange issue that I don't understand though, and I was wondering if someone could explain it.

The issue occurs when trying to set an eventhandler extension method as an event handler of another event. Here is an example of what I'm doing:

public static class EventHandlerExtensions
{
    public static void Raise<TEventArgs>(
        this EventHandler<TEventArgs> eventHandler, 
        object sender, TEventArgs args)  where TEventArgs:EventArgs
    {
        if (eventHandler != null)
        {
            eventHandler(sender, args);
        }
    }
}

public class Test
{
    private event EventHandler<EventArgs> EventA;
    private event EventHandler<EventArgs> EventB;

    public Test()
    {
        Console.WriteLine("::Start");
        EventB += EventA.Raise;
        EventA += (s, a) => Console.WriteLine("Event A raised");
        EventB.Raise(this, EventArgs.Empty);
        Console.WriteLine("::End");
    }
}

In this example, EventA should be triggered as a result of EventB being triggered. However, when I run this code, EventB fires, but the extension method on A doesn't find any listeners for it.

If I change the order around, everything works fine:

Console.WriteLine("::Start");
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB += EventA.Raise;
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");

Also, calling EventA.Raise from a lambda works fine:

Console.WriteLine("::Start");
EventB += (s, a) => EventA.Raise(s, a);
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");

This is just a simple example, but I'm trying to create a class which can re-dispatch events of event sources added to it in the cleanest way possible. I don't want to create named methods just for redispatching the same events, and I'd rather not store lists of lambda functions that I can unhook from the event handlers later. Mostly, I'm just curious as to why this is happening?

Any ideas?

You capture old value of EventA into the closure by your Raise function. Since later you use += it changes value of EventA, but your closure still have an old value.

You code:

EventB += EventA.Raise;
EventA += (s, a) => Console.WriteLine("Event A raised"); 

Can be expanded into equivalent code which makes it clear why you get old delegate:

var oldEventA = EventA;
EventB += oldEventA.Raise; // captures old value here
// now EventA changed to new value 
EventA = oldEventA + ((s, a) => Console.WriteLine("Event A raised");)

You can add following to before EventB += EventA.Raise to verify that code actually raises old event for A:

EventA += (s, a) => Console.WriteLine("Old Event A raised");

Interpreting Django Source Code

4 votes

I was looking through some of the Django source code and came across this. What exactly does: encoding = property(lambda self: self.file.encoding) do?

There's nothing wrong with the other two answers, but they might be a little high-level. So here's the 101 version:

lambda

Although it's in their documentation for C#, I think Microsoft actually has the best explanation of the concept of lambda:

A lambda expression is an anonymous function that can contain expressions and statements

Most people without an official CS degree trip over lambda, but when you think of it as simply an "anonymous function", I think it becomes much easier to understand. The format for lambda in Python is:

lambda [argument]: [expression]

Where [argument] can be nothing, a single argument or a comma-delimited list of arguments and [expression] is essentially the method body. That's why @Jordan said the code you mentioned is roughly the equivalent of:

def encoding(self):
    return self.file.encoding

self is the argument passed into the method and the return value of the method (self.file.encoding) is the expression.

property

The property method allows you to create "getters" and "setters", basically, for an attribute on a class. In traditional OOP, "members", or the attributes of a class, are usually set as protected or private -- you never actually access the attribute directly. Instead, you access methods that in turn retrieve or manipulate the attribute. Chief among those would get the getter and the setter. As their names pretty much describe, they are methods that get and set the value of an attribute, respectively.

Now, Python OOP doesn't really have a concept of protected or private attributes in the truest sense. You are free to follow the rules, but there's nothing stopping you from accessing anything you want on a class. So, getters and setters are most normally, in Python, used in conjunction with property to "fake" an attribute, for lack of a better word. For example:

def get_foo(self):
    return self.bar

def set_foo(self, value):
    self.bar = value

foo = property(get_foo, set_foo)

With that I can now do things like instance.foo (no parenthesis) and instance.foo = 'something'. And it works just as if foo was a regular attribute on the class.

In the code you mention, they're only setting a getter, but it works the same. encoding will act like an attribute on the class and returns the value of file.encoding.