在Matlab中迭代C#迭代器(IEnumerable)
我有一个C#方法,它返回大量的对象。这将在Matlab中使用在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
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