inserting an anonymous method as a value in a generic dictionary ?

B

Bill Woodruff

I've found it's no problem to insert instances of named delegates as values
into a generic dictionary of the form :

private Dictionary<KeyType, Delegate> myDictionary = new
Dictionary<KeyType, Delegate);

using the standard .Add method of the Dictionary, passing in the name of the
delegate instance for the value.

private void myMethodBody()
{
// do some stuff
}

private delegate void myDelegate();

... in some procedure block :

myDelegate myNewDelegate = myMethodBody;

// assume a valid instance of KeyType

myDictionary.Add(myKeyType, myNewDelegate);

But what I really would like to do would be to somehow insert an anonymous
procedure directly as the value of the key in this dictionary.

Okay, so maybe then dictionary value type is no longer 'Delegate : if not,
what would it be ?

But I keep thinking there may be some clever use of anonymous methods to
eliminate the necessity of having to 'package the method body in delegates
as seen here.

I've been experimenting, but have not yet found anything that works.

thanks,

Bill
 
D

David Browne

Bill Woodruff said:
I've found it's no problem to insert instances of named delegates as
values into a generic dictionary of the form :

private Dictionary<KeyType, Delegate> myDictionary = new
Dictionary<KeyType, Delegate);

using the standard .Add method of the Dictionary, passing in the name of
the delegate instance for the value.

private void myMethodBody()
{
// do some stuff
}

private delegate void myDelegate();

... in some procedure block :

myDelegate myNewDelegate = myMethodBody;

// assume a valid instance of KeyType

myDictionary.Add(myKeyType, myNewDelegate);

But what I really would like to do would be to somehow insert an anonymous
procedure directly as the value of the key in this dictionary.

Okay, so maybe then dictionary value type is no longer 'Delegate : if not,
what would it be ?

But I keep thinking there may be some clever use of anonymous methods to
eliminate the necessity of having to 'package the method body in delegates
as seen here.

I've been experimenting, but have not yet found anything that works.

Anonymous methods aren't delegates, so you will need to declare a delegate
type. However you only need one delegate type per anonymous method
signature (perhaps just one). Then you can create instances of the delegate
using anonymous methods.

Like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace csTest
{
class Program
{
private static Dictionary<string, Delegate> myDictionary =
new Dictionary<string, Delegate>();

public delegate void VoidMethod();

static void Main(string[] args)
{
myDictionary.Add("foo", new VoidMethod( delegate
{
Console.WriteLine("Foo");
}));

((VoidMethod)myDictionary["foo"]).Invoke();

}
}
}


David
 
B

Barry Kelly

Bill Woodruff said:
But what I really would like to do would be to somehow insert an anonymous
procedure directly as the value of the key in this dictionary.

An anonymous delegate has no type and permits no operations other than
implicit conversion to compatible delegate types. It needs to be
converted to a delegate type (e.g. System.Windows.Forms.MethodInvoker,
or some other declared delegate type) before you can do anything useful
with it.

Don't forget that a C# anonymous delegate is purely a compiler
construct. To the CLR, there is no such thing as an anonymous delegate,
and the CLR has no type to represent such a thing.

-- Barry
 
B

Bill Woodruff

:

.... original post snipped for brevity ...
Anonymous methods aren't delegates, so you will need to declare a delegate
type. However you only need one delegate type per anonymous method
signature (perhaps just one). Then you can create instances of the
delegate using anonymous methods.

Like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace csTest
{
class Program
{
private static Dictionary<string, Delegate> myDictionary =
new Dictionary<string, Delegate>();

public delegate void VoidMethod();

static void Main(string[] args)
{
myDictionary.Add("foo", new VoidMethod( delegate
{
Console.WriteLine("Foo");
}));

((VoidMethod)myDictionary["foo"]).Invoke();

}
}
}

Thanks, David,

Fascinating example. Because it's very late at night here at GMT + 7 hours
perhaps my mind immediately thinks of making the second argument to the
dictionary (the value type) of type 'VoidMethod :)

I think that means it's time to sleep.

Again, thanks,

Bill
 
B

Bill Woodruff

:
An anonymous delegate has no type and permits no operations other than
implicit conversion to compatible delegate types. It needs to be
converted to a delegate type (e.g. System.Windows.Forms.MethodInvoker,
or some other declared delegate type) before you can do anything useful
with it.

Don't forget that a C# anonymous delegate is purely a compiler
construct. To the CLR, there is no such thing as an anonymous delegate,
and the CLR has no type to represent such a thing.

Thanks, Barry, for helping me get my head on straighter !

best, Bill
 
B

Bill Woodruff

:
((VoidMethod)myDictionary["foo"]).Invoke();

David,

fyi : I am able to use your technique without the casting (to VoidMethod)
you are using above. I am using DynamicInvoke rather than Invoke. And I am
testing with a dictionary with multiple entries. I just happened to run the
test program without yet having inserted the casting call, and, to my
surprise, it worked.

Again, thanks,

best, Bill
 
D

David Browne

Bill Woodruff said:
:
((VoidMethod)myDictionary["foo"]).Invoke();

David,

fyi : I am able to use your technique without the casting (to VoidMethod)
you are using above. I am using DynamicInvoke rather than Invoke. And I am
testing with a dictionary with multiple entries. I just happened to run
the test program without yet having inserted the casting call, and, to my
surprise, it worked.

DynamicInvoke is basically reflection. If the delegate type had arguments
or returned a value then you would have to bundle the arguments into a
object array and downcast the return type.

EG

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace csTest
{
class Program
{
private static Dictionary<string, Delegate> myDictionary =
new Dictionary<string, Delegate>();

public delegate void VoidMethod();
public delegate void VoidMethodString(string arg0);

static void Main(string[] args)
{
myDictionary.Add("foo",
(VoidMethodString)delegate(string value)
{
Console.WriteLine(value);
});

((VoidMethodString)myDictionary["foo"]).Invoke("foo");
myDictionary["foo"].DynamicInvoke(new string[] { "foo" });
}
}
}

David
 
B

Bill Woodruff

bw wrote : snipped for brevity ...
DynamicInvoke is basically reflection. If the delegate type had arguments
or returned a value then you would have to bundle the arguments into a
object array and downcast the return type.

.... snip for brevity ...
(VoidMethodString)delegate(string value)
{
Console.WriteLine(value);
});

((VoidMethodString)myDictionary["foo"]).Invoke("foo");

David, thanks for your thoughts ! I have to admit I am puzzled why you can
do this :

private Dictionary<TreeNode,ListViewItem> nodeDictionary =
new Dictionary<TreeNode,ListViewItem>();

private Dictionary<ListViewItem, TreeNode> LVIDictionary =
new Dictionary<ListViewItem, TreeNode>();

private delegate void theMethod();

private Dictionary<Control, theMethod>
controlMethodDictionary;

controlMethodDictionary = new Dictionary<Control,
theMethod>();

controlMethodDictionary.Add
(
tv1, // treeview
delegate
{
nodeDictionary[tv1.SelectedNode].Selected =
true;
}
);

controlMethodDictionary.Add
(
lv1, // listview
delegate
{
tv1.SelectedNode =
LVIDictionary[lv1.SelectedItems[0]];
}
);

First, I am surprised that I can "plug-in" a Delegate declaration as a Type
in a Generic Dictionary, and then re-use it as you see above.

Appreciate any further thoughts/reactions.

best, Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top