Reputation: 55
So i am making A Queue of Actions, which get invoke at whatever time, what i need is to get each session Queue Position. I've tried doing A Queue of Action, passing the Session name, and than looking up the index, but it always returns -1.
public static Queue<Action<string>> myQ = new Queue<Action<string>>();
static void Main(string[] args)
{
myQ.Enqueue((string i) =>
{
i = "First";
});
myQ.Enqueue((string i) =>
{
i = "Second";
});
myQ.Enqueue((string i) =>
{
i = "Third";
});
int index = myQ.ToList().IndexOf((string i) =>
{
i = "First";
});
Console.WriteLine(index);
Console.ReadLine();
}
Upvotes: 2
Views: 147
Reputation: 31282
List<T>.IndexOf
method searches for specified object in the list. For reference types (and Action<string>
is a reference type) the items are compared by reference equality, i.e. object variables should actually reference the same object.
In your case a new Action<string>
object is created each time when you specify
(string i) =>
{
i = "First";
}
That's the reason why IndexOf()
call returns -1
.
Easiest fix is to pass the same object to IndexOf()
call:
var firstAction = (string i) =>
{
i = "First";
};
myQ.Enqueue(firstAction);
// ...
int index = myQ.ToList().IndexOf(firstAction);
The more flexible approach is to define a simple class that has Session name as a property on which you can search:
public class QueueItem
{
public string SessionName { get; }
public Action<string> Action => i => i = SessionName;
public QueueItem(string sessionName)
{
SessionName = sessionName;
}
}
Queue<QueueItem> myQ = new Queue<QueueItem>();
myQ.Enqueue(new QueueItem("First"));
myQ.Enqueue(new QueueItem("Second"));
myQ.Enqueue(new QueueItem("Thrid"));
int index = myQ.ToList().FindIndex(x => x.SessionName == "First");
Another issue in your code is how you use Action
to assign string variable. Consider this code:
string str = "One";
Action<string> action = x => x = "Two";
action(str);
After execution of this code, value of str
would be "One"
, not "Two"
. When action is called, str
is passed by value so any assignments to the parameter inside an action (or any other method) will not affect its initial value. Check this question for more details.
You could fix that by having Func<string>
instead of Action<string>
and using returned value in assignment:
public class QueueItem
{
public string SessionName { get; }
public Func<string> Func => () => SessionName;
public QueueItem(string sessionName)
{
SessionName = sessionName;
}
}
Queue<QueueItem> myQ = new Queue<QueueItem>();
myQ.Enqueue(new QueueItem("First"));
myQ.Enqueue(new QueueItem("Second"));
myQ.Enqueue(new QueueItem("Thrid"));
var queueList = myQ.ToList();
int index = queueList.FindIndex(x => x.SessionName == "First");
var result = queueList[index].Func();
Upvotes: 1