Take this pseudo example code:
static System.Runtime.InteropServices.ComTypes.IEnumString GetUnmanagedObject() => null;
static IEnumerable<string> ProduceStrings()
{
System.Runtime.InteropServices.ComTypes.IEnumString obj = GetUnmanagedObject();
var result = new string[1];
var pFetched = Marshal.AllocHGlobal(sizeof(int));
while(obj.Next(1, result, pFetched) == 0)
{
yield return result[0];
}
Marshal.ReleaseComObject(obj);
}
static void Consumer()
{
foreach (var item in ProduceStrings())
{
if (item.StartsWith("foo"))
return;
}
}
Question is if i decide to not enumerate all values, how can i inform producer to do cleanup?
Even if you are after a solution using
yield return, it might be useful to see how this can be accomplished with an explicitIEnumerator<string>implementation.IEnumerator<T>derives fromIDisposableand theDispose()method will be called whenforeachis left (at least since .NET 1.2, see here)This is the class implementing
IEnumerable<string>And here we have the core of the solution, the
IEnumerator<string>implementation: