Click here to Skip to main content
15,915,019 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This code create List of methods and random function is working but if i call lista(); it will throw function over and over again - it will not remove them from list, so i will get: TrecePitanje() next PrvoPitanje() next PrvoPitanje() next PrvoPitanje() next TrecePitanje() next DrugoPitanje() .... and so on.
Ps sorry for mine english.




C#
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();
            }




        }


What I have tried:

If i try to count methods in list with
C#
label4.Text = actionList.Count().ToString();

everything looks ok. What i doing wrong?
Posted
Updated 13-Oct-16 5:35am

When you do this

C#
new Action(()=>methodname())


You're executing the methods. Is that really what you want?

Try something like this instead.

C#
// 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);
}


I would also stop using var unless absolutely necessary. Just because the language has a given feature doesn't mean it should be used (I dislike the use of var - it's a personal thing).
 
Share this answer
 
v5
Comments
Member 11383935 13-Oct-16 12:15pm    
I'm sorry, but do not understand what you've done, it return only one method and every time same method is called.
private void button1_Click(object sender, EventArgs e) // sledece - NEXT
{
lista();
}
#realJSOP 13-Oct-16 12:52pm    
No, it's executing the action at the randomly selected index. If that happens to be the same value all the time, that's merely an indication of the poorly implemented "random" class in dotnet. Furthermore, it looked like you wanted to remove the action once it was executed. This further reduces the range of values that the random.Next method can return, thus increasing the odds that the randomly selected index will be the same pretty much every time.
#realJSOP 13-Oct-16 13:00pm    
I commented the code in my solution.
Member 11383935 14-Oct-16 9:11am    
Ok, thanks. Just last question, i should put complete code inside void lista(){} and on a button click just to call lista()
Richard Deeming 13-Oct-16 12:25pm    
No, you're not executing the methods. You're creating a lambda method which will call the wrapped method when it's invoked, and passing that to the Action delegate constructor.

It's essentially equivalent to:
private void MyMethod() { ... }
private void TheLambdaMethod() { MyMethod(); }
...
Action a = new Action(TheLambdaMethod);

Nothing gets called until the delegate is invoked.
The problem may be that you are creating the Random instance inside your loop - and Random initialises itself from the system clock, so if two instances are created close together, they are more than likely going to get the same time, and thus generate the same sequence.

Always create your Random instance as a private class level instance:
C#
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();
            }

Then check that your methods don't call lista themselves!
 
Share this answer
 
Comments
#realJSOP 13-Oct-16 11:40am    
There's more wrong with his code than that.
OriginalGriff 13-Oct-16 11:48am    
:doh:
Yes, you're right.
I need more coffee...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900