473,545 Members | 1,863 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problem passing a Valuetype to a Delegate?

Hi guys,

I create a delegate and pass in a local variable. When the variable
is a reference type everything works fine, but when it is a valuetype
the delegate uses the value of the last instance that was created
(sorry that was a mouthful). Heres an example of the problem:

private void dlgFavorites_Lo ad(object sender, EventArgs e)
{
Hashtable bookmarks =
ConfigurationSe ttings.GetConfi g("Bookmarks" ) as Hashtable;

if(bookmarks == null)
return;

int i = 0;
foreach (DictionaryEntr y pair in bookmarks)
{
Button btn = new Button();
btn.DialogResul t = DialogResult.OK ;
btn.Text = (string)pair.Ke y;

btn.Click += new EventHandler(de legate
{
m_selectedUrl = (string)pair.Va lue;
});
btn.Dock = DockStyle.Fill;

tableLayoutPane l1.Controls.Add (btn, (int)(i/2), i%2);

++i;
}
}

When I ran that, no matter which button was pressed, m_selectedUrl
equaled the value of the last DictionaryEntry in bookmarks. Any
ideas?

Thanks,
James

Apr 11 '07 #1
3 1368
james <ja********@gma il.comwrote:
I create a delegate and pass in a local variable. When the variable
is a reference type everything works fine, but when it is a valuetype
the delegate uses the value of the last instance that was created
(sorry that was a mouthful). Heres an example of the problem:
<snip>

I believe the problem is that "pair" becomes a captured variable, and
its scope is the whole "foreach" loop. If you try changing the delegate
part to:

string value = (string)pair.Va lue;
btn.Click += new EventHandler(de legate
{
m_selectedUrl = value;
});

I think you'll find it's okay.

Here's a short but complete program showing the same kind of thing in
effect with a for loop:

using System;

class Test
{
delegate void SimpleDelegate( );

static void Main()
{
SimpleDelegate[] delegates = new SimpleDelegate[10];

for (int i=0; i < delegates.Lengt h; i++)
{
delegates[i] = delegate { Console.WriteLi ne(i); };
}

foreach (SimpleDelegate dg in delegates)
{
dg();
}
}
}

That prints "10" each time, because the "i" variable is effectively
shared between all the delegate instances. Change it so that the scope
of the variable used is *within* the loop, and it's fine:

using System;

class Test
{
delegate void SimpleDelegate( );

static void Main()
{
SimpleDelegate[] delegates = new SimpleDelegate[10];

for (int i=0; i < delegates.Lengt h; i++)
{
int j = i;
delegates[i] = delegate { Console.WriteLi ne(j); };
}

foreach (SimpleDelegate dg in delegates)
{
dg();
}
}
}

That prints 0 to 9.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 11 '07 #2
Thanks Jon that clears things up. I'm still trying to wrap my brain
around what the runtime is doing, but it makes sense nonetheless.

-James

Apr 12 '07 #3
james <ja********@gma il.comwrote:
Thanks Jon that clears things up. I'm still trying to wrap my brain
around what the runtime is doing, but it makes sense nonetheless.
I think the word "scope" was probably not the most helpful one to use -
think about it in terms of the *lifetime* of the variable. The loop
variable is "alive" for the whole loop, and so it's shared between all
the delegates. Effectively, it's only declared once. The variables
within the loop block, however, are effectively "redeclared " each time
you go through the loop - so the variable on the first iteration of the
loop is a different variable to the one in the second iteration of the
loop.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 12 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1708
by: john | last post by:
Hi,All Gurus: It is kind of complicated, please bear with me and let me know if you have any questions. Thanks a lot in advance. John I have a csharp method, using emit to dynamically generate classes & method depends on the meta table in the database,here is my problem 1) One method I generated works when it was called, but another set...
6
2285
by: Joanna Carter \(TeamB\) | last post by:
Hi folks I have a Generic Value Type and I want to detect when the internal value changes. /////////////////////////////// public delegate void ValueTypeValidationHandler<T>(T oldValue, T newValue); public struct TestType<T> {
0
278
by: Aryeh Holzer | last post by:
Let me start with a quote from the C# Programmers Reference (where I learned the cool word "covariance"): "When a delegate method has a return type that is more derived than the delegate signature, it is said to be covariant. Because the method's return type is more specific than the delegate signature's return type, it can be implicitly...
3
1767
by: Wild Wind | last post by:
Hello, I made a post relating to this issue a while back, but I haven't received any answer, so here I am again. I am writing a mixed C++ dll which uses the following declaration: typedef System::Byte ByteArray __gc;
5
2049
by: Kevin Yu | last post by:
hi all since the DateTime can't be assign null, the min value is set to 1901 or something, if in a application design, the date field can be null, so in between the UI and the DB, the business logic has to take care of the conversion?? e.g when inserting DateTime.minvalue into db, (especially when using store precedure, it seems that pass...
0
2005
by: Haxan | last post by:
Hi, I have an unmanaged application that converts a function pointer to a delegate and then pass this as a parameter(delegate) to a managed function which then invokes it. Currently Im able to jump to this unmanaged function, but the values of the parameters inside this function Im seeing are not correct(they have some garbage values). ...
2
4933
by: darthghandi | last post by:
I am trying to pass a socket object when an event is signaled. I have successfully bound to a network interface and listened on a port for incoming connection. I have also been able to accept that connection and get the socket. I try to signal an event when this happens and pass that new socket object when the event happens, but when I try...
9
2654
by: Jerome Durand | last post by:
Hello, I'm trying to write something along the following lines but I cannot get this to compile. template <typename derivedstruct Base { typedef typename derived::valueType valueType; virtual valueType Value() = 0; };
5
2742
by: VictorG | last post by:
Hello, I am trying to secure a webservice using WSE 3.0 and the turnkey usernameForCertificateSecurity profile. I am passing a valid username token, and on the server I have overridden the Authenticate token call and it is being called. My ASP.NET service has a Login() method and it is being called during client application startup....
0
7487
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7420
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7680
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7778
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
4966
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3476
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3459
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1908
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1033
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.