I have a C# method that returns very large number of objects. This is to be consumed in Matlab.
namespace MyNameSpace{
public static class MyClass{
public static IEnumerable<MyDataObject> GetVeryLargeResponse(){
while(CheckForSomeFunkyConditionThatsRarelyTrue()){
yield return GetMyNextDataObject();
}
yield break;
}
}
}
In Matlab when I make a call
result = MyClass.GetVeryLargeResponse();
I would expect result to be of type IEnumerable<MyDataObject>
, so as to be able to get the Enumerator<MyDataObject>
by calling result.GetEnumerator()
.
Where as I'm getting result
which is of type MyNameSpace.<GetVeryLargeResponse>d_3
with no GetEnumerator()
method available. I do see one of result
's Super class being System.Collections.Generic.IEnumerable<MyClass>
.
Is there a way I can iterate over this in Matlab or even to 'cast' result
to IEnumerable<MyClass>
in Matlab.
p.s.
Array
/ IList
etc is not feasible due to data volumeIQueryable
specifically.The looping can be defined as repeating the same process multiple times until a specific condition satisfies. It is known as iteration also. There are three types of loops used in the C language.
An iterator is an object that allows you to step through the contents of another object, by providing convenient operations for getting the first element, testing when you are done, and getting the next element if you are not. In C, we try to design iterators to have operations that fit well in the top of a for loop.
C – Iterate over Array using While Loop To iterate over Array using While Loop, start with index=0, and increment the index until the end of array, and during each iteration inside while loop, access the element using index.
The result does have a GetEnumerator()
method - it's just may be implemented with explicit interface implementation.
If Matlab isn't willing to handle that, you could always write your own mapping type and an extension method to make things simpler:
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();
}
}
Then try:
result = MyClass.GetVeryLargeResponse().Wrap();
It seems very odd for Matlab not so support this out of the box though...
Consider the following example:
namespace MyNameSpace {
public class Person {
public string name { get; set; }
public int age { get; set; }
}
public class MyClass {
private static List<Person> people = new List<Person> {
new Person {name = "name1", age=10},
new Person {name = "name2", age=20},
new Person {name = "name3", age=30},
new Person {name = "name4", age=40},
new Person {name = "name5", age=50}
};
public static IEnumerable<Person> GetPeople() {
foreach (var p in people) {
yield return p;
}
}
}
}
%# load my assembly
str = 'C:\path\to\MyNameSpace.dll';
NET.addAssembly(str);
obj = MyNameSpace.MyClass.GetPeople(); %# IEnumerable<Person>
%# call ToArray() extension method: this forces immediate query evaluation
NET.addAssembly('System.Core'); %# contains 'System.Linq' namespace
arr = NET.invokeGenericMethod('System.Linq.Enumerable', 'ToArray', ...
{'MyNameSpace.Person'}, obj);
%# loop through results
for i=1:arr.Length
fprintf('name=%s, age=%d\n', char(arr(i).name), int32(arr(i).age));
end
The code produces the output:
name=name1, age=10
name=name2, age=20
name=name3, age=30
name=name4, age=40
name=name5, age=50
As you can see, I did convert the returned object as an array Person[]
(which I realize you were trying to avoid). The weird thing is if you if we look at the hierarchy of classes:
>> 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
you can see the System.Collections.Generic.IEnumerator<Person>
, but somehow the object doesn't seem to expose the inherited GetEnumerator
method:
>> methods(obj,'-full')
Methods for class MyNameSpace.<GetPeople>d__0:
MyNameSpace.<GetPeople>d__0 obj <GetPeople>d__0(int32 scalar <>1__state)
logical scalar RetVal Equals(MyNameSpace.<GetPeople>d__0 this, System.Object obj)
int32 scalar RetVal GetHashCode(MyNameSpace.<GetPeople>d__0 this)
System.Type RetVal GetType(MyNameSpace.<GetPeople>d__0 this)
System.String RetVal ToString(MyNameSpace.<GetPeople>d__0 this)
event.listener L addlistener(handle sources, char vector eventname, function_handle scalar callback) % Inherited from handle
event.proplistener L addlistener(handle sources, meta.property properties, char vector eventname, function_handle scalar callback) % Inherited from handle
event.proplistener L addlistener(handle sources, string propertyname, char vector eventname, function_handle scalar callback) % Inherited from handle
event.proplistener L addlistener(handle sources, cell propertynames, char vector eventname, function_handle scalar callback) % Inherited from handle
delete(handle obj) % Inherited from handle
logical TF eq(A, B) % Inherited from handle
handle HM findobj(handle H, varargin) % Inherited from handle
meta.property prop findprop(handle scalar object, string propname) % Inherited from handle
logical TF ge(A, B) % Inherited from handle
logical TF gt(A, B) % Inherited from handle
logical validity isvalid(handle obj) % Inherited from handle
logical TF le(A, B) % Inherited from handle
logical TF lt(A, B) % Inherited from handle
logical TF ne(A, B) % Inherited from handle
notify(handle sources, string eventname) % Inherited from handle
notify(handle sources, string eventname, event.EventData scalar eventdata) % Inherited from handle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With