I have a usercontrol with an internal list which I have exposed publically by implementing IEnumerable. When I use foreach to enumerate over it, the usercontrol gets disposed. Why is this happening?
Example to reproduce:
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
public class VanishingControl : UserControl, IEnumerable, IEnumerator
{
string[] strings = { "uno", "due", "tres" };
int position = -1;
public IEnumerator GetEnumerator()
{
return this;
}
public object Current
{
get { return strings[position]; }
}
public bool MoveNext()
{
position++;
return position < strings.Length;
}
public void Reset()
{
position = 0;
}
protected override void Dispose(bool disposing)
{
Console.WriteLine("bye!");
base.Dispose(disposing);
}
}
public class Vanish : Form
{
private VanishingControl vc = new VanishingControl();
public Vanish()
{
vc.BackColor = Color.Black;
vc.Click += vc_Click;
Controls.Add(vc);
}
void vc_Click(object sender, EventArgs e)
{
foreach (string s in vc)
Console.WriteLine(s);
}
[STAThread]
static void Main()
{
Application.Run(new Vanish());
}
}
Run it in the debugger and click the black square.
One of the interfaces implemented by IEnumerator
is IDisposable
. The foreach
loop will call Dispose
on the source of the loop once it's done processing the items.
A much better solution would be to factor your UserControl
into 2 parts
UserControl
minus the enumerable interfacesFor example
public class VanishingControl : UserControl
{
string[] strings = { "uno", "due", "tres" };
public IEnumerable<string> GetItems() {
foreach (var current in strings) {
yield return current;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With