C# - 创建随机获取值的Enumeraor

时间:2014-11-27 06:34:06

标签: c# ienumerable ienumerator

我想在C#中创建一个IEnumerable类,当获取下一个值从对象列表中随机获取

我希望每次想要获得下一个随机值,例如我的列表长度为100,每次获得随机值时获得1000次值

我创建了一个下面的类,但是当我从类

创建新实例时,我的程序被挂起了
public class MyEnumerable:System.Collections.IEnumerable
{
    public int RegionID { get; set; }

    List<Medium> RankedList;
    MediaEnumerator pe;

    public MyList(int regionID)
    {
        RegionID = regionID;
        RankedList = ShowVideo.GetRankList(regionID);
        pe = new MediaEnumerator(RankedList);
    }

    public System.Collections.IEnumerator GetEnumerator()
    {
        return (IEnumerator)(pe);
    }
}

public class MediaEnumerator : IEnumerator
{
    List<Medium> RankedList;
    int position = -1;

    public MediaEnumerator(List<Medium> list)
    {
        RankedList = list;
    }

    Random rnd = new Random();

    public bool MoveNext()
    {
        position = rnd.Next(RankedList.Count);
        return true;
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public FileInfo Current
    {
        get
        {
            try
            {
                FileInfo fi = new FileInfo(RankedList[position].MediaUrl);
                return fi;
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您可以通过混合LINQ和GUID以随机顺序获取任何可枚举。

var randomOrder = originalEnumerable.OrderBy(o => new Guid());

答案 1 :(得分:1)

iteratorsRandom和无限循环一起使用将是最简单的解决方案。

public IEnumerable<T> GetRandomElements<T>(T[] elements)
{
    Random rand = new Random();
    while(true)
    {
        int index = rand.Next(0, elements.Length);
        yield return elements[index];
    }
}

答案 2 :(得分:0)

我认为你的问题是你总是在MoveNext()中返回true,更改此代码可能会导致代码工作正常

但现在有一个错误,即获取随机值的数量正是您的列表长度的数字。但我修好了你的代码。

    public bool MoveNext()
    {
        position++;
        return (position < RankedList.Count);
        //position = rnd.Next(RankedList.Count);
        //return true;
    }

并在MediaEnumerator中更改此代码

    public FileInfo Current
    {
        get
        {
            try
            {
                //FileInfo fi = new FileInfo(RankedList[position].MediaUrl);
                FileInfo fi = new FileInfo(RankedList[rnd.Next(RankedList.Count)].MediaUrl);
                return fi;
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }