8 votes

Passer une méthode en tant qu'argument

J'ai une méthode SaveChanges(T objet) qui est fréquemment appelée dans mon code, sauf qu'en fonction de l'action appelant la méthode, il y aurait une méthode différente appelée depuis SaveChanges. Quelque chose comme ça...

protected void SaveChanges(T objetMla, SomeFunction(arg))
    where T : WebObject
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        SomeFunction(arg);
    }
}

Exemples d'utilisation :

SaveChanges(article, article.Authors.Remove(person)) //person est un objet de type MlaPerson
//OU
SaveChanges(article, article.RelatedTags.Remove(tag)) //tag est un objet de type Tag
//OU
SaveChanges(article, article.RelatedWebObjects.Remove(location)) //location est un objet de type MlaLocation

J'ai lu sur les méthodes déléguées mais je suis un peu confus sur la façon de les mettre en œuvre avec mes exigences ou si mes exigences nécessitent l'utilisation de délégués.

ÉDIT : Serait-il également possible de passer plusieurs Actions ?

10voto

user7116 Points 39829

Que diriez-vous de :

protected void SaveChanges(T mlaObject, Action rollback)
    where T : WebObject
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        rollback(mlaObject);
    }
}

Appelé comme suit :

this.SaveChanges(myObj, x => article.Authors.Remove(x));

Maintenant, après avoir relu votre question, je ne vois pas l'intérêt de passer le mlaObject car il n'est jamais utilisé.

// this.SaveChanges(
//     () => article.Authors.Remove(author),
//     () => article.RelatedTags.Remove(tag));
protected void SaveChanges(params Action[] rollbacks)
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        foreach (var rollback in rollbacks) rollback();
    }
}

// Surcharge pour supporter le rollback avec un argument
// this.SaveChanges(
//     author,
//     article.Authors.Remove,
//     authorCache.Remove);
protected void SaveChanges(T arg, params Action[] rollbacks)
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        foreach (var rollback in rollbacks) rollback(arg);
    }
}

7voto

James Michael Hare Points 19077

METTRE À JOUR J'ai été un peu vague dans votre question si l'argument passé est utilisé ailleurs dans la méthode, il ne semble pas l'être, vous pouvez donc simplement prendre une Action et utiliser une lambda pour spécifier le délégué à appeler avec l'argument capturé:

protected void SaveChanges(T mlaObject, TArg arg, Action undoFunction)
    where T : WebObject
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        undoFunction();
    }
}

À laquelle vous pouvez passer :

SaveChanges(article, () => article.Authors.Remove(person));

Ou si c'est l'objet lui-même, auquel cas (comme sixlettervariables l'a déjà répondu) vous pouvez simplement le renvoyer dans un délégué selon son code.

Ou, si l'arg est différent de mlaObject et que vous voulez également faire d'autres choses avec dans le code, auquel cas vous pourriez faire :

protected void SaveChanges(T mlaObject, TArg arg, Action undoFunction)
    where T : WebObject
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        undoFunction(arg);
    }
}

Et ensuite avoir :

SaveChanges(article, person, article.Authors.Remove);

5voto

BFree Points 46421
protected void SaveChanges(T mlaObject, Action action, U arg)
    where T : WebObject
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Erreur : " + e);
        action(arg);
    }
}

J'espère avoir bien compris la question...

4voto

Jamiec Points 35773

Votre méthode SaveChanges ressemblerait à ceci :

protected void SaveChanges(T mlaObject, TArg arg, Action someFunction)
    where T : WebObject
{
   ...
}

Appelée comme suit :

SaveChanges(article,person, (article,person) =>  article.Authors.Remove(person))

0voto

Bjorn Coltof Points 449
protected void SaveChanges(T mlaObject, Action functionToCall)
{
    try { this._db.SaveChanges(); }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e);
        functionToCall(mlaObject);
    } 
}

Appeler comme ceci :

SaveChanges(actualArticle, article => article.Authors.Remove(person));

J'ai laissé de côté la partie WebObject car elle n'était pas utilisée du tout dans la fonction.

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