2 Replies - 4707 Views - Last Post: 15 May 2013 - 10:18 AM

#1 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2506
  • View blog
  • Posts: 4,615
  • Joined: 24-September 10

Lambda Expressions vs Small Token Objects

Posted 15 May 2013 - 08:03 AM

(examples written in vb.net because I'm at work... when I'm at work I'm in VB.net mode, when I'm at home I'm in C# mode. I wouldn't exactly call this a VB.Net problem because it really pertains to how .Net constructs are managed in the .Net Runtime)

So I have a design question, and I want some opinions.

I have a situation where I need to save up a list of commands that can be called later on, repeatedly.

What I'm going to do is create a List(Of Command) and place each command into it, then have a method that can be called to loop over each command and call it.

So I started by imagining it where 'Command' is an abstract type, and each Command inherits (or implements if I use an interface) this Command and does its unique command operation and defines its required parameters.

Public Class CommandSetCache

	Private _commands As New List(Of ICommand)()

	Public Sub DoA(ByVal arg1 As Blargh)
		_commands.Add(New CommandA(arg1))
	End Sub

	Public Sub DoB(ByVal arg1 As Blargh, ByVal arg2 As Bleep)
		_commands.Add(New CommandB(arg1, arg2))
	End Sub

	Public Sub DoCached()
		For Each cmnd In _commands
			cmnd.Invoke()
		Next
	End Sub

	Private Interface ICommand
		Sub Invoke()
	End Interface
	
	Private Class CommandA
		Implements ICommand
		
		Public Arg1 As Blargh
		
		''imply constructor
		
		Public Sub Invoke() Implements ICommand.Invoke
			Arg1.Foo("doing a")
		End Sub
		
	End Class
	
	Private Class CommandB
		Implements ICommand
		
		Public Arg1 As Blargh
		Public Arg2 As Bleep
		
		''imply constructor
		
		Public Sub Invoke() Implements ICommand.Invoke
			Arg1.Foo("doing b with " & Arg2)
		End Su
		
	End Class
	
End Class



But then I considered, I could probably shorten up all this code just using lambda expressions. As follows:

Public Class CommandSetCache

	Private _commands As New List(Of Action)()

	Public Sub DoA(ByVal arg1 As Blargh)
		_commands.Add(Sub()
							arg1.Foo("doing a")
					  End Sub)
	End Sub

	Public Sub DoB(ByVal arg1 As Blargh, ByVal arg2 As Bleep)
		_commands.Add(Sub()
							arg1.Foo("doing b with" & arg2)
					  End Sub)
	End Sub

	Public Sub DoCached()
		For Each cmnd In _commands
			cmnd()
		Next
	End Sub

End Class



My concern though is, there could be TONS of these commands spread across multiple 'CommandSetCache' objects. I know the memory implications of the class/interface example, but the lambda expression scenario... I don't know what the memory implications are. I don't know how they nicely they compile up.

Does anyone with extensive experience with lambdas tell me if the lambda example has any loops holes. I do understand the scoping implications, I have that covered. I just mean if excessive use of lambdas like this may cause for memory issues I don't know about.



Currently standing, I'm going forward with lambdas. Unless someone can give me some reason not to.

This post has been edited by lordofduct: 15 May 2013 - 08:04 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Lambda Expressions vs Small Token Objects

#2 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5643
  • View blog
  • Posts: 12,359
  • Joined: 16-October 07

Re: Lambda Expressions vs Small Token Objects

Posted 15 May 2013 - 08:51 AM

This:
void Foo() { Print("Foo"); }
void Bar() { Print("Bar"); }
//...
var cmds = new List<Action>();
cmds.Add(Foo);
cmds.Add(Bar);
foreach (var cmd in cmds) { cmd(); }




Should be fundamentally identical to this:
var cmds = new List<Action>();
cmds.Add(Foo);
cmds.Add(Bar);
foreach (var cmd in cmds) { cmd(); }



What's interesting is when you put on your closure hat.

Is this:
interface ICmd { void Run(); }

class CmdTest : ICmd {
	private readonly int x, y;
	public CmdTest(int x, int y) { this.x = x; this.y = y;  }
	private int DoWork() { return x * y; }
	public void Run() { Print(DoWork()); }
}

var cmds = new List<ICmd>();
cmds.Add(new CmdTest(3, 5));
cmds.Add(new CmdTest(8, 13));
foreach (var cmd in cmds) { cmd.Run(); }



The same as:
int DoWork(int x, int y) { return x * y; }
var cmds = new List<Action>();
cmds.Add(() => Print(DoWork(3, 5)));
cmds.Add(() => Print(DoWork(8, 13)));
foreach (var cmd in cmds) { cmd(); }



I believe your Action model should be lighter weight. If nothing else, it shouldn't be any worse. However, I have nothing solid to base that on.

It does seem a whole lot cleaner and on that alone I'd use it.
Was This Post Helpful? 0
  • +
  • -

#3 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2506
  • View blog
  • Posts: 4,615
  • Joined: 24-September 10

Re: Lambda Expressions vs Small Token Objects

Posted 15 May 2013 - 10:18 AM

Yeah, that's my gut feeling as well.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1