I have a method: int[] GetNumbers ();
which immediately returns array of numbers. However I can call this method only when class is initialized. I cannot initialize this class manually, it is initialized somewhere else by someone else.
I want to create IEnumerable
which will call GetNumbers()
when I will start iterating over that enumerable.
example:
IEnumerable<int> numbers = new SomeKindOfWrapper (() => GetNumbers());
Now GetNumbers()
will be called only when I try to access numbers
.
How to achieve this? Is there something in NET framework that supports it?
I can pass delegate to my class which will call GetNumbers(), but I prefer IEnumerable.
Simply create an iterator block that invokes the delegate and then yields the values in the sequence:
public static IEnumerable<T> SomeKindOfWrapper<T>(
Func<IEnumerable<T>> generator)
{
foreach(var item in generator())
yield return item;
}
If you want to ensure that the delegate is never invoked more than once you can use Lazy
instead:
public static IEnumerable<T> SomeKindOfWrapper<T>(
Lazy<IEnumerable<T>> sequence)
{
foreach(var item in sequence.Value)
yield return item;
}
One kind of wrapper that you could use is Lazy<T>
:
Lazy<IEnumerable<int>> numbers = new Lazy<IEnumerable<int>>(() => GetNumbers());
You can use numbers.Value
, or add a wrapper property for it:
IEnumerable<int> Numbers {
get {
return numbers.Value;
}
}
The call of GetNumbers()
is deferred until the first call of numbers.Value
. After that the result is stored inside Lazy<T>
, and returned to you on subsequent calls of numbers.Value
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.