如果没有越界,则从数组中获取值
本文关键字:获取 数组 越界 如果没有 | 更新日期: 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];
}