20

在 C# 中,我试图从随机索引的列表中获取一个项目。检索到它后,我希望将其删除,以便不再选择它。似乎我需要很多操作才能做到这一点,难道没有一个函数可以让我简单地从列表中提取一个项目吗?RemoveAt(index) 函数无效。我想要一个有返回值的。

我在做什么:

List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);

do
{
  int index = rand.Next(numLst.Count);
  int extracted = numLst[index]; 
  // do something with extracted value...
  numLst.removeAt(index);
}
while(numLst.Count > 0);

我想做的事:

List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);

do
{
  int extracted = numLst.removeAndGetItem(rand.Next(numLst.Count)); 
  // do something with this value...
}
while(numLst.Count > 0);

是否存在这样的“removeAndGetItem”功能?

4

2 回答 2

23

不,因为它违反了纯函数礼仪,其中一个方法要么有副作用,要么返回一个有用的值(即不仅仅是指示错误状态)——绝不是两者兼而有之。

如果您希望函数看起来是原子的,您可以获取列表上的锁,这将阻止其他线程在您修改列表时访问列表,前提是它们也使用lock

public static class Extensions
{
    public static T RemoveAndGet<T>(this IList<T> list, int index)
    {
        lock(list)
        {
            T value = list[index];
            list.RemoveAt(index);
            return value;
        }
    }
}
于 2013-03-01T09:18:48.210 回答
8
public static class ListExtensions
{
  public static T RemoveAndGetItem<T>(this IList<T> list, int iIndexToRemove}
  {
    var item = list[iIndexToRemove];
    list.RemoveAt(iIndexToRemove);
    return item;
  } 
}

这些称为扩展方法,称为 as new List<T>().RemoveAndGetItem(0)

扩展方法中需要考虑的事项

使用您传递的索引进行异常处理,在执行此操作之前检查索引是否为 0 和列表的计数。

于 2013-03-01T09:12:53.167 回答