我有一个函数返回一个只读的值列表。在某些情况下,这个值列表可能会变得非常大,可以通过算法来描述。我希望列表按请求动态生成这些值,而不是生成包含所有这些值的列表。如果我需要自己实现更多算法,是否有任何通用或模板或其他任何可以让我开始的东西?
我意识到这个想法本身是相当通用的,但我把它作为一个起点标记为我的具体案例。
答案 0 :(得分:2)
由于List<T>
表示内存中的集合,因此无法在不将其存储在内存中的情况下动态生成其成员。
但是,您可以使用IEnumerable<T>
:在循环中使用yield return
语句动态生成序列的项目:
public IEnumerable<int> RandomlyIncreasing() {
var rnd = new Random();
var current = rnd.Next(0, 50);
for (int i = 0 ; i != 1000000 ; i++) {
yield return current;
current += rnd.Next(0, 10);
}
}
答案 1 :(得分:0)
正如dasblinkenlight所述,List
必须包含元素。根据其实现的接口IList
和ICollection
的定义。如果您想返回代表值列表的内容,则IEnumerable
是您唯一的选择。检查此实现。
public class FunctionBasedList<T> : IEnumerable<T>
{
public class Enumerator<T> : IEnumerator<T>
{
private int index;
private T current;
private FunctionBasedList<T> list;
internal Enumerator(FunctionBasedList<T> list)
{
this.list = list;
}
public T Current {
get
{
return current;
}
}
Object IEnumerator.Current
{
get
{
if (index == 0 || index == this.list.Count + 1)
{
throw new InvalidOperationException();
}
return current;
}
}
public bool MoveNext()
{
if (list.Count > index)
{
current = this.list[index];
index++;
return true;
}
return false;
}
public void Reset()
{
index = 0;
current = default(T);
}
public void Dispose()
{
}
}
public int Count
{
private set;
get;
}
public Func<int, T> Function
{
private set;
get;
}
public T this[int index]
{
get
{
if (index < 0 || index >= this.Count)
{
throw new IndexOutOfRangeException();
}
return this.Function(index);
}
}
public FunctionBasedList(int count, Func<int, T> function)
{
this.Count = count;
this.Function = function;
}
public Enumerator<T> GetEnumerator()
{
return new Enumerator<T>(this);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Enumerator<T>(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator<T>(this);
}
}
class Program
{
static void Main(string[] args)
{
FunctionBasedList<int> readOnlyList = new FunctionBasedList<int>(
10,
(index) =>
{
//Arbitrary function to generate a specific value for a specific index
return index * 100;
});
foreach (int r in readOnlyList)
{
Console.WriteLine(r);
}
//Loop through a subset of the list
for (int i = 5; i < 8; i++)
{
Console.WriteLine(readOnlyList[i]);
}
//Will throw an IndexOutOfRangeException
Console.WriteLine(readOnlyList[10]);
}
}
您可以返回IEnumerator
,并在不同情况下使用List<T>
或FunctionBasedList<T>
。