数组的结构是什么?

时间:2016-03-21 14:03:12

标签: c# arrays foreach

我知道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;

的任意属性

在这个循环中,它是一种访问属性,但如何? 这里的财产本身是什么?他们是如何组织的?

2 个答案:

答案 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.使用ListDictionary或更复杂的东西),它的工作方式会略有不同,即使用EnumeratorIDisposable。请注意,这只是一个编译器优化,数组完全能够处理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表示特定类型;在您的情况下intSystem.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());
}