I have a requirement where I need to know the calling method to the GetEnumerator()
.
The best way I could think would be possibly overriding the default behaviour to GetEnumerator
to one that I create i.e GetEnumerator([CallerMemberName]string caller = null)
but I cannot seem to do this as anything calling it still goes to the original one.
public class MyItems : IEnumerable<string>
{
private List<string> items = new List<string>();
public MyItems()
{
items.Add("One");
items.Add("Two");
items.Add("Three");
items.Add("Four");
items.Add("Five");
items.Add("Six");
}
public IEnumerator<string> GetEnumerator()
{
return items.GetEnumerator();
}
public IEnumerator<string> GetEnumerator([CallerMemberName]string caller = null)
{
var method = caller;
return items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
Example of some calling code could be
private void button1_click(object sender,EventArgs e)
{
MyItems items = new MyItems();
foreach (var item in items)
{
}
}
The aim is that I would want to know for example "button1_click"
in the GetEnumerator()
method
I don't think it's possible to do exactly what you want to do, since foreach
, to my knowledge, always calls the GetEnumerator()
without any arguments. However, I see two possibilities to your issue
You can use a StackTrace
to get the calling method:
public IEnumerator<string> GetEnumerator()
{
StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
return items.GetEnumerator();
}
or you can use another method instead of the GetEnumerator()
which takes the [CallerMemberName]
attribute.
public IEnumerable<string> Iterate([CallerMemberName]string caller = null)
{
Console.WriteLine(caller);
return items;
}
foreach (var myItem in items.Iterate())
{
//..
}