假设我想在一个类中存储无限数量的元素,就像 Excel 对工作表的数量所做的那样(受计算机内存的限制)。
保存用于获取元素的索引的方式或数字类型是什么?
如果你想存储一个任意大的整数,你可以使用BigInteger
.
public BigInteger Index{ get; set; }
请注意,您必须首先添加对System.Numerics
dll 的引用。
它与 .NET Framework 中的其他整数类型不同,后者具有由其MinValue
和MaxValue
属性指示的范围。
因为它没有上限或下限,所以任何导致值增长过大OutOfMemoryException
的操作都可以抛出。BigInteger
如果你想滚动你自己的集合,你可以使用Indexer。以下简单示例可以处理 100 个元素,但您可以使用 List 或其他机制将其扩展到所需的任意数量的元素:
class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
// Define the indexer, which will allow client code
// to use [] notation on the class instance itself.
public T this[int i]
{
get
{
// This indexer is very simple, and just returns or sets
// the corresponding element from the internal array.
return arr[i];
}
set
{
arr[i] = value;
}
}
}
此类显示客户端代码如何使用索引器:
class Program
{
static void Main(string[] args)
{
// Declare an instance of the SampleCollection type.
SampleCollection<string> stringCollection = new SampleCollection<string>();
// Use [] notation on the type.
stringCollection[0] = "Hello, World";
System.Console.WriteLine(stringCollection[0]);
}
}
// Output:
// Hello, World.
使用 anint
作为索引器参数将使您可以访问大约 20 亿个离散元素。如果您需要更多,则必须使用long
或任意精度类型,BigInt
如索引器参数。
Tim-Schmelter 和 Joseph Lee 为您提供了很好的答案。但考虑到它们是最大化价值的好答案。但是,请考虑实现的细节:如果您的数据结构只有一个字节,那么在考虑任何其他因素(数据结构等)之前,即使是 ULong 也可以索引超过 EB 的值。
任何数值类型的变量都是有限的。我所知道的最大的是 ULong(0 到 18,446,744,073,709,551,615)。如果你有比这更多的元素,你就有麻烦了......
在 .Net 中,任何特定对象都有 2Gb 的限制。这意味着,例如,byte[]
数组索引不能大于int.MaxValue
- 实际上它甚至更小。
因此,您可以轻松地将Int32
==int
用于任何索引,或者您应该仔细考虑您的数据结构。
要索引仅受可用系统内存限制的项目集合,您可能可以使用long
. 该范围足以唯一地寻址存储库的各个位,该存储库的大小几乎是TACC Stampede 的14PB 驱动器空间大小的 150 倍(或超过其 207TB 主存储器库大小的 10000 倍)。
根据 Tim Schmelter 的回答:
public class BigList<T>
{
public Object[] internalArray = new Object[Int16.MaxValue];
public T this[BigInteger i]
{
get
{
if (i < Int16.MaxValue-1)
{
return (T)internalArray[(int)i];
}
else
{
i = i - int.MaxValue;
BigList<T> following = (BigList<T>)internalArray[Int16.MaxValue-1];
if (following != null)
{
return following[i];
}
else
{
throw new KeyNotFoundException();
}
}
}
set
{
if (i < Int16.MaxValue-1)
{
internalArray[(int)i] = value;
}
else
{
i = i - int.MaxValue;
BigList<T> following = (BigList<T>)internalArray[Int16.MaxValue-1];
if (following == null)
{
following = new BigList<T>();
internalArray[Int16.MaxValue - 1] = following;
}
following[i] = value;
}
}
}
}
并开始单元测试:
[Test]
public void BigListTest()
{
BigList<string> test = new BigList<string>();
var bigIndex = new BigInteger(int.MaxValue);
string value = "test";
bigIndex *= 2;
test[bigIndex] = value;
Assert.AreEqual(test[bigIndex],value);
}