我知道C#中的Array是一个对象 但实际上有点代码使我感到困惑
int[] numbers = {4, 5, 6, 1, 2, 3, -2, -1, 0};
foreach (int i in numbers)
Console.WriteLine(i);
访问任意对象int value= object.property;
在这个循环中,它是一种访问属性,但如何? 这里的财产本身是什么?他们是如何组织的?
答案 0 :(得分:3)
如何存储数据
基本上,数组是一团数据。整数是32位有符号整数的值类型。
C#中的标识符是指向对象的指针或实际值。在引用类型的情况下,它们是真正的指针,在值类型(例如int,float等)的情况下,它们是实际数据。 int
是值类型,int[]
(数组到整数)是引用类型。
它的工作原理基本上是“效率”:复制4个字节或8个字节的值类型的开销非常小,而复制整个数组的开销可能非常大。
如果你有一个包含N个整数的数组,它只不过是一个N * 4字节的blob,变量指向第一个元素。 blob中的每个元素都没有名称。
E.g:
int[] foo = new int[10]; // allocates 40 bytes, naming the whole thing 'foo'
int f = foo[2]; // allocates variable 'f', copies the value of 'foo[2]' into 'f'.
访问数据
至于foreach ...在C#中,所有集合都实现了一个名为IEnumerable<T>
的接口。如果你使用它,编译器在这种情况下会注意到它是一个整数数组,它将遍历所有元素。换句话说:
foreach (int f in foo) // copy value foo[0] into f, then foo[1] into f, etc
{
// code
}
(在数组的情况下!)与:
完全相同for (int i=0; i<foo.Length; ++i)
{
int f = foo[i];
// code
}
请注意,我在这里明确地将“在数组的情况下”。数组是C#编译器的特例。如果您不使用数组(但f.ex.使用List
,Dictionary
或更复杂的东西),它的工作方式会略有不同,即使用Enumerator
和IDisposable
。请注意,这只是一个编译器优化,数组完全能够处理IEnumerable
。
对于那些感兴趣的人,基本上它会为非数组和非字符串生成这个:
var e = myEnumerable.GetEnumerator();
try
{
while (e.MoveNext())
{
var f = e.Current;
// code
}
}
finally
{
IDisposable d = e as IDisposable;
if (d != null)
{
d.Dispose();
}
}
如果您想要一个名字
您可能需要Dictionary
。
答案 1 :(得分:0)
数组只是一个集合,或IEnumerable<T>
T
表示特定类型;在您的情况下int
(System.Int32
)
内存分配......
int是32位长,你想要一个包含10个项目的数组
int[] numbers = new int[10];
32 x 10 =分配320位内存
内存访问...
假设您的数组从0000:0000
开始,并且您想要访问数组的索引n [0-9]
...
伪代码......
index = n
addressof(n) = 0000:0000 + (sizeof(int) * index)
或
index = 2
addressof(n) = 0000:0000 + (32 * 2)
这是一个简化的示例,说明当您访问数组中的每个索引项时会发生什么(您的foreach循环排序是这样做的)
foreach循环通过引用数组中的每个元素来工作(在您的情况下,引用称为i)。
为什么您不能通过财产访问...
在数组中,项目按索引存储,而不是按名称存储......
......所以你不能......
numbers.1
numbers.2
......但你可以......
numbers[1]
numbers[2]
由于每个对象都派生自object,因此您可以访问特定类型的任意成员......
numbers[1].GetHashCode();
示例:强>
//Define an array if integers, shorthand (see, memory allocation)...
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//For each element in the array (under the hood, get the element's address in memory and hold this in a reference called i)...
foreach(int i in numbers)
{
// Call GetHashCode() on the instance pointed to by i and pass the reference (by value) to the Console.WriteLine method.
Console.WriteLine(i.GetHashCode());
}