最近VB FAQ提到了一个问题——VB.NET支持非零下标数组吗?答案是不支持。即使VB2005有这样的语法Dim a(0 To 10) As String,那个“0”也不能是别的数字。CLR在某种程度上支持非零下标数组,但C#这样有C传统的语言一开始就设计成只支持零下标,如果VB支持非零下标数组,各种语言的交互将会变得困难。关于这个问题,详细讨论请见这里。在FAQ中,另一篇帖子讨论了解决方法,就是用一个类模拟数组的行为,用默认属性(或索引器,C#)来模拟数组的下标。但是原文提到,没有泛型的情况下,我们需要为每一种类型创建一个非零下标的数组类。现在我们不但有了泛型,还有运算符重载,可以做一个更加清晰、漂亮的非零下标数组类。在动手以前,我发现C#还支持迭代器,可以令我的类更加方便,于是就用了C#,后面给出VB调用它的例子。
/// <summary>
/// 表示一个下标可以不是零的数组
/// </summary>
/// <typeparam name="T">数组元素的类型</typeparam>
public class VBArray<T> : IEnumerable<T>
{
private T[] arr;
private int _LBound;
public int LBound
{
get
{
return _LBound;
}
}
public int UBound
{
get
{
return _LBound + arr.Length - 1;
}
}
public VBArray(int LBound, int UBound)
{
if (UBound < LBound)
{
throw new ArgumentException("上界不能小于下界");
}
_LBound = LBound;
arr = new T[UBound - LBound + 1];
}
public T this[int index]
{
get
{
return arr[index - _LBound];
}
set
{
arr[index - _LBound] = value;
}
}
public void ReDim(int UBound)
{
if (UBound < _LBound)
{
throw new ArgumentException("上界不能小于下界");
}
arr = new T[UBound - _LBound + 1];
}
public static implicit operator T[](VBArray<T> vbarr)
{
return vbarr.arr;
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < arr.Length; i++)
{
yield return arr[i];
}
}
}
以下代码为VB调用该类的例子。
Dim o As New VBArray(Of Integer)(3, 15)
o(3) = 5
o(4) = 6
o(10) = 10
o(15) = -1
MsgBox(o(10))
For Each x As Int32 In o
MsgBox![]()
Next
通过重载的运算符,可以将VBArray转换为普通的数组,这样就可以在需要操作数组的上下文使用VBArray中的数值。
打印 | 张贴于 2004-04-30 13:20:00 | Tag:技术随笔
留言反馈