在Matlab中迭代C#迭代器(IEnumerable)

在Matlab中迭代C#迭代器(IEnumerable),c#,.net,matlab,C#,.net,Matlab,我有一个C#方法,它返回大量的对象。这将在Matlab中使用 namespace MyNameSpace{ public static class MyClass{ public static IEnumerable<MyDataObject> GetVeryLargeResponse(){ while(CheckForSomeFunkyConditionThatsRarelyTrue()){ yield

我有一个C#方法,它返回大量的对象。这将在Matlab中使用

namespace MyNameSpace{
    public static class MyClass{
        public static IEnumerable<MyDataObject> GetVeryLargeResponse(){
            while(CheckForSomeFunkyConditionThatsRarelyTrue()){
               yield return GetMyNextDataObject();
            }
            yield break;
        }
    }
}
我希望结果的类型为
IEnumerable
,以便能够通过调用
result.GetEnumerator()
来获取
枚举器

其中,当我得到
result
时,它的类型为
MyNameSpace.d_3
,没有可用的
GetEnumerator()
方法。我确实看到
result
的超类之一是
System.Collections.Generic.IEnumerable

有没有一种方法可以在Matlab中迭代,甚至可以在Matlab中将
结果
转换为
IEnumerable

namespace MyNameSpace{
    public static class MyClass{
        public static IEnumerable<MyDataObject> GetVeryLargeResponse(){
            while(CheckForSomeFunkyConditionThatsRarelyTrue()){
               yield return GetMyNextDataObject();
            }
            yield break;
        }
    }
}
p、 美国

  • 由于数据量大,无法转换为
    数组
    /
    IList
  • 这不是重复的,因为它专门处理
    IQueryable
  • 我正在使用Matlab2010b
  • 结果确实有一个
    GetEnumerator()
    方法-它可以通过显式接口实现来实现

    如果Matlab不愿意处理这个问题,您可以编写自己的映射类型和扩展方法,使事情变得更简单:

    public static class Extensions
    {
        public static EnumerableWrapper<T> Wrap<T>(this IEnumerable<T> source)
        {
            return new EnumerableWrapper<T>(source);
        }
    }
    
    public class EnumerableWrapper<T> : IEnumerable<T>
    {
        private readonly IEnumerable<T> source;
    
        public EnumerableWrapper(IEnumerable<T> source)
        {
            this.source = source;
        }
    
        public IEnumerator<T> GetEnumerator()
        {
            return new EnumeratorWrapper<T>(source.GetEnumerator());
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    
    public class EnumeratorWrapper<T> : IEnumerator<T>
    {
        private readonly IEnumerator<T> source;
    
        public EnumeratorWrapper(IEnumerator<T> source)
        {
            this.source = source;
        }
    
        public T Current { get { return source.Current; } }
    
        object IEnumerator.Current { get { return Current; } }
    
        public bool MoveNext()
        {
            return source.MoveNext();
        }
    
        public void Reset()
        {
            source.Reset();
        }
    
        public void Dispose()
        {
            source.Dispose();
        }
    
    }
    

    Matlab不支持这种开箱即用的方法,这似乎很奇怪…

    考虑以下示例:

    MyClass.cs 如您所见,我确实将返回的对象转换为数组
    Person[]
    (我知道您试图避免)。奇怪的是,如果我们看看类的层次结构:

    >> superclasses(obj)
    Superclasses for class MyNameSpace.<GetPeople>d__0:
        System.Object
        System.Collections.Generic.IEnumerable<MyNameSpace*Person>
        System.Collections.IEnumerable
        System.Collections.Generic.IEnumerator<MyNameSpace*Person>
        System.IDisposable
        System.Collections.IEnumerator
        handle
    

    您需要使用显式强制转换。首先显式强制转换IEnumerable实例:

    result = MyClass.GetVeryLargeResponse();
    resultEnumerable = NET.explicitCast(result,'System.Collections.IEnumerable');
    
    然后获取枚举数:

    resultEnumerator = resultEnumerable.GetEnumerator();
    
    resultEnumerator = NET.explicitCast(resultEnumerator, 'System.Collections.IEnumerator');
    
    然后显式强制转换枚举数:

    resultEnumerator = resultEnumerable.GetEnumerator();
    
    resultEnumerator = NET.explicitCast(resultEnumerator, 'System.Collections.IEnumerator');
    
    然后,您可以根据需要迭代集合:

    while (resultEnumerator.MoveNext)
        resultEnumerator.Current
    end
    

    非常聪明的解决方案-虽然它也需要一个枚举器包装器,但它非常合适。我仍然很想知道Matlab中的解决方案是什么,因为C#代码可能并不总是在我们的控制之下。@YetAnotherUser:为了完整性,将为
    IEnumerator
    添加包装器。恐怕我从来没有使用过Matlab,所以我也没办法…看看我的解决方案,看看如何在Matlab中实现它。很抱歉,我提出了一个老帖子,但是如果你不需要创建一个包装类型,你就不能
    AsEnumerable
    完成你在这里要做的事情吗?@Servy:这么多年后,我不清楚我为什么在这里做任何事。看起来OP查看的是
    IEnumerable
    的执行时类型,而不是编译时类型。我将编辑一点…是的,这正是导致问题的原因。正如@Jon Skeet所指出的,这可能是因为显式接口实现实现了
    IEnumerable
    ——这意味着我们需要在Matlab中将其显式转换为
    IEnumerable
    。不确定我们是否有办法在Matlab中做到这一点。@YetAnotherUser查看我关于如何使用显式强制转换的答案。
    resultEnumerator = resultEnumerable.GetEnumerator();
    
    resultEnumerator = NET.explicitCast(resultEnumerator, 'System.Collections.IEnumerator');
    
    while (resultEnumerator.MoveNext)
        resultEnumerator.Current
    end