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