2 votes

trouver l'index d'une action particulière en file d'attente

Je suis en train de créer une file d'attente d'actions, qui sont invoquées à n'importe quel moment, ce dont j'ai besoin c'est d'obtenir la position de chaque session dans la file d'attente. J'ai essayé de faire une file d'attente d'actions, en passant le nom de la session, puis en cherchant l'index, mais cela renvoie toujours -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();
}

1voto

CodeFuller Points 20614

List<T>.IndexOf La méthode recherche l'objet spécifié dans la liste. Pour les types de référence (et Action<string> est un type de référence), les éléments sont comparés par égalité de référence, c'est-à-dire que les variables d'objet doivent effectivement référencer le même objet.

Dans votre cas, une nouvelle Action<string> est créé à chaque fois que vous spécifiez

(string i) =>
{
    i = "First";
}

C'est la raison pour laquelle IndexOf() les retours d'appels -1 .

La solution la plus facile est de passer le même objet à IndexOf() appeler :

var firstAction = (string i) =>
        {
            i = "First";
        };
myQ.Enqueue(firstAction);

// ...

int index = myQ.ToList().IndexOf(firstAction);

L'approche la plus souple consiste à définir une classe simple dont le nom de la session est une propriété sur laquelle vous pouvez effectuer une recherche :

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");

Un autre problème dans votre code est la façon dont vous utilisez Action pour affecter une variable de type chaîne. Considérez ce code :

string str = "One";
Action<string> action = x => x = "Two";
action(str);

Après l'exécution de ce code, la valeur de str serait "One" pas "Two" . Lorsque l'action est appelée, str est passé par valeur, de sorte que toute affectation au paramètre dans une action (ou toute autre méthode) n'affectera pas sa valeur initiale. Vérifiez ceci question pour plus de détails.

Vous pouvez corriger cela en ayant Func<string> au lieu de Action<string> et utiliser la valeur renvoyée dans l'affectation :

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();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X