Enumerate如何在MonoTouch中工作?

时间:2011-09-22 10:49:03

标签: xamarin.ios nsset enumerate

在MonoTouch中,我需要处理NSSet中的每个对象。我使用Enumerate的尝试如下:

public override void ReturnResults ( BarcodePickerController picker, NSSet results )
{
    var n = results.Count;  // Debugging - value is 3
    results.Enumerate( delegate( NSObject obj, ref bool stop ) 
    {
        var foundCode = ( obj as BarcodeResult ); // Executed only once, not 3 times
        if ( foundCode != null )
        {
            controller.BarcodeScannedResult (foundCode);
        }
    });
// Etc
}

虽然在结果中使用三个对象调用该方法,但在委托中只处理一个对象。我本来希望代表被执行三次,但我必须对它是如何工作有错误的想法。

无法找到任何文档或示例。任何建议都非常感激。

2 个答案:

答案 0 :(得分:6)

您必须将ref参数设置为false。这指示处理程序继续枚举:

if ( foundCode != null )
{
    controller.BarcodeScannedResult (foundCode);
    stop = false; // inside the null check
}

Here是Apple文档中的ObjC等价物。

答案 1 :(得分:0)

或者您可以尝试使用此扩展方法,以便更轻松..

public static class MyExtensions {
    public static IEnumerable<T> ItemsAs<T>(this NSSet set) where T : NSObject {
        List<T> res = new List<T>();
        set.Enumerate( delegate( NSObject obj, ref bool stop ) {
            T item = (T)( obj ); // Executed only once, not 3 times
            if ( item != null ) {
                res.Add (item);
                stop = false; // inside the null check
            }
         });

         return res;
    }
}   

然后你可以做类似的事情:

foreach(BarcodeResult foundCode in results.ItemsAs<BarcodeResult>()) {
    controller.BarcodeScannedResult (foundCode);
}

注意:请记住,这会创建另一个列表并将所有内容复制到其中,效率较低。我这样做是因为匿名方法中不允许“yield return”,而我可以想到的另一种方法是让它成为一个没有副本的真正的枚举器。我处理的大多数套装都很小,所以这并不重要,但是如果你有一套很大的套装,这并不理想。