填充数组以避免索引超出数组错误范围的方法

Kob*_*kie 5 c# arrays data-structures indexoutofboundsexception

我希望在查询时我的列表中至少有183个项目,但有时我的提取结果会导致项目数低于183.我的当前修复假定在计数小于183的情况下填充数组.

if (extractArray.Count() < 183) {
    int arraysize= extractArray.Count();
    var tempArr = new String[183 - arraysize];
    List<string> itemsList = extractArray.ToList<string>();
    itemsList.AddRange(tempArr);
    var values = itemsList.ToArray();
    //-- Process the new array that is now at least 183 in length
}
Run Code Online (Sandbox Code Playgroud)

但似乎我的解决方案并不是最好的.我将不胜感激任何其他解决方案可以帮助确保每当提取物发生时我至少得到183个项目.

pho*_*oog 7

我可能会关注他人的建议,并使用一个列表.使用"capacity"构造函数来增加性能:

var list = new List<string>(183);
Run Code Online (Sandbox Code Playgroud)

然后,每当你得到一个新数组时,执行此操作(将""替换为用于填充数组的任何值):

list.Clear();
list.AddRange(array);
// logically, you can do this without the if, but it saves an object allocation when the array is full
if (array.Length < 183)
    list.AddRange(Enumerable.Repeat(" ", 183 - array.Length));
Run Code Online (Sandbox Code Playgroud)

这样,列表总是重用相同的内部数组,从而减少分配和GC压力.

或者,您可以使用扩展方法:

public static class ArrayExtensions
{
    public static T ElementOrDefault<T>(this T[] array, int index)
    {
        return ElementOrDefault(array, index, default(T));
    }
    public static T ElementOrDefault<T>(this T[] array, int index, T defaultValue)
    {
        return index < array.Length ? array[index] : defaultValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样的代码:

items.Zero = array[0];
items.One = array[1];
//...
Run Code Online (Sandbox Code Playgroud)

变成这样:

items.Zero = array.ElementOrDefault(0);
items.One = array.ElementOrDefault(1);
//...
Run Code Online (Sandbox Code Playgroud)

最后,这是一个相当麻烦的想法,我开始写这个答案:你可以将数组包装在一个IList实现中,该实现保证有183个索引(为简洁起见,我省略了大多数接口成员实现):

class ConstantSizeReadOnlyArrayWrapper<T> : IList<T>
{
    private readonly T[] _array;
    private readonly int _constantSize;
    private readonly T _padValue;

    public ConstantSizeReadOnlyArrayWrapper(T[] array, int constantSize, T padValue)
    {
         //parameter validation omitted for brevity
        _array = array;
        _constantSize = constantSize;
        _padValue = padValue;
    }

    private int MissingItemCount
    {
        get { return _constantSize - _array.Length; }
    }

    public IEnumerator<T> GetEnumerator()
    {
        //maybe you don't need to implement this, or maybe just returning _array.GetEnumerator() would suffice.
        return _array.Concat(Enumerable.Repeat(_padValue, MissingItemCount)).GetEnumerator();
    }

    public int Count
    {
        get { return _constantSize; }
    }

    public bool IsReadOnly
    {
        get { return true; }
    }

    public int IndexOf(T item)
    {
        var arrayIndex = Array.IndexOf(_array, item);
        if (arrayIndex < 0 && item.Equals(_padValue))
            return _array.Length;
        return arrayIndex;
    }

    public T this[int index]
    {
        get
        {
            if (index < 0 || index >= _constantSize)
                throw new IndexOutOfRangeException();
            return index < _array.Length ? _array[index] : _padValue;
        }
        set { throw new NotSupportedException(); }
    }
}
Run Code Online (Sandbox Code Playgroud)

确认.


Ste*_*eve 5

Array 基类实现Resize方法

if(extractArray.Length < 183)
    Array.Resize<string>(ref extractArray, 183);
Run Code Online (Sandbox Code Playgroud)

但是,请记住,调整大小会影响性能,因此此方法仅在出于某种原因需要数组时才有用。如果可以切换到列表

而且,我假设您在这里有一个一维字符串数组,因此我使用 Length 属性来检查数组中的有效项数。