tags:

views:

126

answers:

3

If I use a lambda expression like the following

// assume sch_id is a property of the entity Schedules
public void GetRecord(int id)
{
    _myentity.Schedules.Where(x => x.sch_id == id));
}

I'm assuming (although non-tested) I can rewrite that using an anonymous inline function using something like

_jve.Schedules.Where(delegate(Models.Schedules x) { return x.sch_id == id; });

My question is, how would I rewrite that in a normal (non-inline) function and still pass in the id parameter.

+7  A: 

The short answer is that you can't make it a stand-along function. In your example, id is actually preserved in a closure.

The long answer, is that you can write a class that captures state by initializing it with the id value you want to operate against, storing it as a member variable. Internally, closures operate similarly - the difference being that they actually capture a reference to the variable not a copy of it. That means that closures can "see" changes to variables they are bound to. See the link above for more details on this.

So, for example:

public class IdSearcher
{
     private int m_Id; // captures the state...
     public IdSearcher( int id ) { m_Id = id; }
     public bool TestForId( in otherID ) { return m_Id == otherID; }
}

// other code somewhere...
public void GetRecord(int id)
{
    var srchr = new IdSearcher( id );
    _myentity.Schedules.Where( srchr.TestForId );
}
LBushkin
id isn't a closure itself; it's just the state stored within the closure.
Jon Skeet
A: 

You would need to save the ID somewhere. This is done for you by using a closure, which basically is like creating a separate, temporary class with the value and the method.

Reed Copsey
+1  A: 

If you only want to place the body of the delegate somewhere else you can achieve using this

public void GetRecord(int id)
{
    _myentity.Schedules.Where(x => MyMethodTooLongToPutInline(x, id));
}
private bool MyMethodTooLongToPutInline(Models.Schedules x, int id)
{
    //...
}
Marcel Gosselin