将数组从VBA转换为C#(最佳实践)

3

我已经将大约4000-5000行的VBA代码转换为C#。唯一的问题是:


在VBA中,您可以创建一个类型的数组,并设置开始索引。例如:

//This creates an Array with an index 5 to index 100.
doubleArray(5 To 100) As Double

在C#中不可能创建一个从0以外的索引开始的数组。(请参见下面的链接。)我认为这将留下以下两种可能性:

1. 创建一个从0到100的doubleArray

我可以按照以下方式创建一个doubleArray:

Double[] doubleArray = new Double[100];

这种方法的优点是我可以使用VBA代码中描述的索引号来设置索引。这意味着以下内容:VBA代码假定数组从[5]到[100]存在,而我也能够在C#中将数字5设置为100。

但是,在我看来,这相当混乱,因为您始终会创建具有未使用内存的数组(在此示例中为索引[0]到索引[4])。因此,我考虑了第二个选项。

2. 从0到((topindex-bottomindex)+1)创建doubleArray

我可以按以下方式创建doubleArray:

Double[] doubleArray = new Double[((topindex - bottomindex) + 1)];

在我看来,这应该是“最干净”的解决问题的方法,避免不必要的内存使用。在VBA中,数组使用[5]到[100],这使得长度为96。对于这个选项也是一样的(((100-5)+1)=96)。
然而,最大的缺点是这也需要忽略已经编写的所有代码。如果任何函数调用doubleArray [97],它应该是doubleArray [((97-5)+1)]。
我的问题是如何处理这种情况?
如果其他人看到另一个选项/可能性,欢迎提出建议。
更多背景信息,请参考我之前的问题的后续: Vba Type-Statement conversion to C#

我会选择第二个,因为你提到的原因。 - Tripp Kinetics
你可以创建一个包装器,围绕数组使用索引器来应用偏移量。可选择提供一种使用传统的基于0的索引的方法。 - Jeff Mercado
从技术上讲,你可以使用C#创建具有非零下界的数组。不过,如果有人在我的工作场所引入这样的代码,我可能会考虑解雇他们。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 就像我下面所说的,这个源代码不是我写的。 - Revils
2个回答

3

三个步骤:

  1. 在VBA中创建每个数组实例的单元测试。

  2. 将所有的VBA数组调整为以零为基础,并检查其是否符合单元测试的要求。

  3. 转移到C#。

我很想避免跨语言界限引入错误,因为调和问题更加困难。


我非常喜欢你的解决方案,但是将数组从零开始可能会很困难,因为例如; 25岁是年龄,所以在索引[25]处,双精度值是年龄为25岁的人的结果。(我没有自己编写源代码,否则我会使用类。) - Revils
这就是单元测试的作用。在C#中,以零为基础的数组是如此惯用,以至于每个人都会期望该特定数组的表示法为1 + 年龄。 - Bathsheba

1
I'd选择#2,但这里还有另一个解决方案供您参考。
您也可以创建一个自定义类,只需在其中放置一个数组。您将执行3个方法:
1.设置元素(myObject.setElement(6,0.12)) 2.获取元素(myObject.getElement(6)) 3.第一个是设置数组大小(myObject.setSize(5,100))
实际上,当您获取或设置元素时,将转到索引(index-5)
您可以创建的类示例
    public class CustomArray {
      private Double[] myArray;
      private int spread;

      public CustomArray(){
        setSize(5,100);
      }

      public void setSize (int lowerIndex, int upperIndex){
        myArray = new Double[(upperIndex-lowerIndex)+1]
        spread = lowerIndex
      }

      public Double getElement(int index){
        return myArray[index-spread];
      }

      public void setElement(int index, Double element){
        myArray[index-spread] = element;
      }
    }

(PS:我已经有一年没有使用C#编程了,所以可能会有一些语法错误,但代码是为了更好地理解)

1
我明白了,就像Jeff Mercado所说的包装类一样。我一定会尝试的! - Revils
1
一个需要注意的是,使用包装类可能会严重影响一些较大的多维数组的应用程序性能! - Revils

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接