2013-10-06 48 views
1

C#数组,为什么没有一个具有负数作为索引的数组?这种情况有时非常有用;特别是对于一些特殊类型的排序中的快速算法。两个问题:1)为什么不呢? 2)任何有效的解决方法?为什么不用一个负数作为索引的数组?

+2

您可以使用“Dictionary”从负数映射到别的东西。 –

+0

您可以创建一个派生自链接列表的类,并重载[]运算符以使用数组。 – TomF

+1

你的意思是-1应该返回数组中的最后一个元素吗? – ProgramFOX

回答

3

您可以随时使用indexer实现自己的班级。例如:

public class MyClass { 
    public String this[int index] { 
     get { 
      // ... 
     } 

     set { 
      // ... 
     } 
    } 
} 

其中String为返回类型为例。

2

在某些语言中,数组从零开始,因为数据结构对项目的底层偏移量从零开始。这是最简单的实现方式,它使程序员可以最好地使用它。

有些语言允许使用其他基本索引,但是从索引计算偏移量需要额外的成本。在简单的代码中你获得了什么,你会失去一个更复杂的数组实现。

最有效的解决方法是在访问数组时自行调整索引。还有其他解决方案可以提供更清晰的代码,但效率不高。例如,您可以将数组包装到一个类中,并提供一个索引器来调整索引,从而实现具有合理开销的无缝实现。

2

您可以创建自己的类,该类将包装数组并在访问时提供索引转换。你会想要写这样的事情:

public class ArrayWithAnyIndexes<ArrayType> 
{ 

    private ArrayType[] arrayToWrap; 
    private int firstIndex; 

    public ArrayWithAnyIndexes(ArrayType[] arrayToWrap, int firstIndex) 
    { 
    this.arrayToWrap = arrayToWrap; 
    this.firstIndex = firstIndex; 
    } 

    public ArrayTypethis[int index] { 
     public get { 
      return this.arrayToWrap[index - firstIndex]; 
     } 

     public set { 
      this.arrayToWrap[index - firstIndex] = value; 
     } 
    } 

} 
2

Array.CreateInstance method可以在理论上可以用来与非零下界创建数组:

Array.CreateInstance(
    elementType: typeof(T), 
    lengths: new int[] { length }, 
    lowerBounds: new int[] { lowerBound }); 

唯一的问题是,C#韩元不允许你将返回的数组转换为T[];这只会是允许的,并且适用于多维数组(T[,]等)。

这很可能在某种程度上是由于CLR专门处理一个下界为零的一维数组;这些被称为“矢量”并得到一些特殊的优化,既不是多维数组也不是具有非零下界的数组。

但是事实上,我不确定为什么恰恰是 C#将一维数组限制为向量。

+0

Interresting,但是当我尝试调用它时,我得到'System.InvalidCastException:无法将类型为'System.String [*]'的对象转换为键入'System.String []'。 – Guffa

+0

@Guffa:哦,男孩......你说得对。我刚刚检查了我的“CLR通过C#”的副本。这种转换对于一维数组是不可能的。这使得我的答案毫无用处,但我会在纠正状态下将其留在那里。 – stakx

+1

你可以将你在'IList'接口的**非泛型**版本的答案中创建的'T [*]'数组强制转换。然后你可以像'T read =(T)arr [-12];'和'arr [-12] = write;'那样访问它。不幸的是,你不能使用带'T [*]'数组的通用'IList '接口;只适用于'T []'。 –

相关问题