如果没有越界,则从数组中获取值

本文关键字:获取 数组 越界 如果没有 | 更新日期: 2023-09-27 17:49:46

我正在寻找最优雅的解决方案,当请求的索引不越界时,从object[]获取值。

我目前的解决方案如下:

    public object GetNamedParametersFrom(GenericObject genericObject)
    {
        string nameFromListOne = String.Empty;
        string nameFromListTwo = String.Empty;
        for (int i = 0; i < genericObject.ListOfThings.Count; i++)
        {
            switch (i)
            {
                case 0:
                    nameFromListOne = genericObject.ListOfThings[i].Name;
                    break;
                case 1:
                    nameFromListTwo = genericObject.ListOfThings[i].Name;
                    break;
            }
        }
        return new {
           nameFromListOne,
           nameFromListTwo
        }
    }

如果没有越界,则从数组中获取值

为什么不使用Linq内置的ElementAtOrDefault方法?

string[] names =
    { "Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow",
        "Hedlund, Magnus", "Ito, Shu" };
int index = 20;
string name = names.ElementAtOrDefault(index);

为什么不使用Array ?

public object GetNamedParametersFrom(GenericObject genericObject)
{
    string[] namesFromLists = new string[genericObject.ListOfThings.Count];
    for (int i = 0; i < genericObject.ListOfThings.Count; i++)
    {
        namesFromLists[i] = genericObject.ListOfThings[i].Name;
    }
    return namesFromLists; //As you are returning an `object`, you can return `resources` array directly from this method
}

如何扩展方法:

public static TValue GetSafe<TItem, TValue>(this IList<TItem> list, 
    int index, Func<TItem, TValue> selector, TValue defaultValue)
{
  // other checks omitted
  if (index < 0 || index >= list.Count)
  {
    return defaultValue;
  }
  return selector(list[index]);
}

你可以这样使用:

var items = new[] {"Hello", "World", "!"};
var value0 = items.GetSafe(0, s => s.Length, 0);
var value1 = items.GetSafe(1, s => s.Length, 0);
var value2 = items.GetSafe(2, s => s.Length, 0);
var value3 = items.GetSafe(3, s => s.Length, 0);

最后一行不会抛出错误,value3将被设置为0 (defaultValue)。

我知道这是一个公认的答案,但在我看来,一个更优雅、更简单的解决方案是这样的:

var item = items.Length > n
                ? resourceProperties[n]
                : <default value you want to return if it's out of bounds>;

其中items为集合

正如Rasmus所说,使用LINQ的ElementAtOrDefault是最好的选择。如果不能保证元素的数量,可以添加一些NULL检查。

string[] fruits = { "Apples", "Oranges", "Blueberries", "Pineapple" };
string? thirdFruit = fruits?.ElementAtOrDefault(2); // Blueberries
string? tenthFruit = fruits?.ElementAtOrDefault(9); // NULL
string? negativeFruit = fruits?.ElementAtOrDefault(-1); // NULL

如果您只是想通过输入请求的index来获得一个resource

   if(index < object.Resources.Count){
         resource = object.Resources[index].Name;
    }

使用扩展方法

public T TryGetElement<T>(this T[] array, int index, T defaultElement) {
  if ( index < array.Length ) {
    return array[index];
  }
  return defaultElement;
}

像这样使用

// Select name to a string[]
var names = @object.Resources.Select(i => i.Name).ToArray();
resourceOne = names.TryGetElement(0, null);
resourceTwo = names.TryGetElement(1, null);

Eric的方法很好;但是应该对数组做一个完整的边界检查:

public T ElementOrDefault<T>(this T[] array, int index, T defaultElement) {
  if ( index < array.GetLowerBound(0) || index > array.GetUpperBound(0) ) {
    return defaultElement;
  }
  return array[index];
}
相关文章: