所以我正在创建一个动作队列,它可以在任何时间调用,我需要的是获得每个会话队列位置。 我尝试过做一个行动队列,传递会话名称,而不是查找索引,但总是返回-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();
}
答案 0 :(得分:1)
List<T>.IndexOf
方法搜索列表中的指定对象。对于引用类型(并且Action<string>
是引用类型),项目通过引用相等性进行比较,即对象变量实际上应该引用相同的对象。
在您的情况下,每次指定
时都会创建一个新的Action<string>
对象
(string i) =>
{
i = "First";
}
这就是IndexOf()
调用返回-1
的原因。
最简单的修复方法是将同一个对象传递给IndexOf()
调用:
var firstAction = (string i) =>
{
i = "First";
};
myQ.Enqueue(firstAction);
// ...
int index = myQ.ToList().IndexOf(firstAction);
更灵活的方法是定义一个简单的类,该类具有会话名称作为您可以搜索的属性:
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");
代码中的另一个问题是如何使用Action
分配字符串变量。请考虑以下代码:
string str = "One";
Action<string> action = x => x = "Two";
action(str);
执行此代码后,str
的值为"One"
,而不是"Two"
。调用操作时,str
按值传递,因此对操作(或任何其他方法)内的参数的任何赋值都不会影响其初始值。有关详细信息,请查看此question。
您可以通过Func<string>
代替Action<string>
并在分配中使用返回值来解决此问题:
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();