Member 11383935 Ответов: 2

Нужна помощь с созданием списка методов и случайным вызовом методов из списка


Этот код создает список методов и случайная функция работает, но если я вызову листа(); он будет бросать функцию снова и снова - он не удалит их из списка, так что я получу: Трецепитанье() следующий Првопитанье() следующий Првопитанье() следующий Првопитанье() следующий Трецепитанье() следующий Другопитанье() ... и так далее.
Ps извините за мой английский.




public void lista()
        {
       

            var actionList = new[]
                {
                    new Action( () => PrvoPitanje() ),
                    new Action( () => DrugoPitanje() ),
                    new Action( () => TrecePitanje() )
                }.ToList();
            
        
            label4.Text = actionList.Count().ToString(); // To Check -1 
            
            while (actionList.Count() > 0)
            {
            var r = new Random();
            var index = r.Next(actionList.Count());
            var action = actionList[index];
            actionList.RemoveAt(index);
            action();
            }




        }


Что я уже пробовал:

Если я попытаюсь подсчитать методы в списке с помощью
label4.Text = actionList.Count().ToString();

все выглядит нормально. Что я делаю не так?

2 Ответов

Рейтинг:
2

#realJSOP

Когда вы это сделаете

new Action(()=>methodname())


Вы выполняете методы. Ты действительно этого хочешь?

Попробуйте вместо этого что-нибудь подобное.

// Use a list instead of casting a var to a list (that's inefficient)
List<Action> actionList = List<Action>()
{
    // there's no need to do "new Action here"
    PrvoPitanje,
    DrugoPitanje,
    TrecePitanje
};

// instantiate the random object outside the loop
Random r = new Random();
// while we have an action in the list
while (actionList.Count() > 0)
{
    // If the list contains more than one item, randomly select the index.
    // Otherwise, just take the first and only item in the list (there's
    // no use in randomly selecting the next item when there's only one in
    // the list.
    int index = (actionList.Count > 1) ? r.Next(0,actionList.Count()-1) : 0;
    // execute the action
    actionList[index]();
    // remove it from the list
    actionList.RemoveAt(index);
}


Я бы также перестал использовать var без крайней необходимости. Просто потому, что язык имеет определенную функцию, это не значит, что он должен использоваться (мне не нравится использование var - это личное дело).


Member 11383935

Мне очень жаль, но я не понимаю, что вы сделали, он возвращает только один метод и каждый раз вызывается один и тот же метод.
частный недействительными обработчика button1_click(объект отправителя, EventArgs в е) // sledece - следующий
{
листа();
}

Richard Deeming

Нет, вы не выполняете методы. Вы создаете лямбда-метод, который будет вызывать обернутый метод при его вызове и передавать его в Action конструктор делегатов.

Это по существу эквивалентно:

private void MyMethod() { ... }
private void TheLambdaMethod() { MyMethod(); }
...
Action a = new Action(TheLambdaMethod);

Ничто не вызывается до тех пор, пока не будет вызван делегат.

#realJSOP

Нет, он выполняет действие по случайно выбранному индексу. Если это все время одно и то же значение, то это просто признак плохо реализованного "случайного" класса в dotnet. Кроме того, это выглядело так, как будто вы хотели удалить действие, как только оно было выполнено. Это еще больше уменьшает диапазон значений, которые случайны.Следующий метод может вернуться, тем самым увеличивая вероятность того, что случайно выбранный индекс будет практически каждый раз одинаковым.

#realJSOP

Я прокомментировал код в своем решении.

Member 11383935

Ладно, спасибо. Просто последний вопрос, я должен поместить полный код внутри void lista () {} и нажать кнопку, чтобы вызвать lista()

Рейтинг:
0

OriginalGriff

Проблема может заключаться в том, что вы создаете случайный экземпляр внутри своего цикла - и случайный инициализирует себя из системных часов, поэтому, если два экземпляра создаются близко друг к другу, они, скорее всего, получат одно и то же время и, таким образом, сгенерируют одну и ту же последовательность.

Всегда создавайте свой случайный экземпляр как частный экземпляр уровня класса:

private Random rand = new Random();
        public void lista()
        {
            var actionList = new[]
                {
                    new Action( () => PrvoPitanje() ),
                    new Action( () => DrugoPitanje() ),
                    new Action( () => TrecePitanje() )
                }.ToList();
            label4.Text = actionList.Count().ToString(); // To Check -1 
            while (actionList.Count() > 0)
            {
                var index = rand.Next(actionList.Count());
                var action = actionList[index];
                actionList.RemoveAt(index);
                action();
            }

Затем убедитесь, что ваши методы сами не вызывают lista!


#realJSOP

С его кодом что-то не так.

OriginalGriff

:до:
Да, вы правы.
Мне нужно еще кофе...