IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comment simplifier ce code ?


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut Comment simplifier ce code ?
    Bonjour,

    Les 2 méthodes ci-dessous font la même chose, mais j'ai du en créer 2 car j'ai 2 appels de fonctions different : Func<int, double> et Func<int, DateTime, double>.

    Existe-t-il une manière de réécrire cela de manière à ne garder plus qu'une seule procédure ?

    Merci beaucoup.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
            public static double SumItem(Func<int, double> method, int startPeriodIncluded, int endPeriodIncluded)
            {
                double sumItem = 0;
                for (int j = startPeriodIncluded; j < endPeriodIncluded + 1; j++)
                {
                    sumItem += method(j);
                }
                return sumItem;
            }
     
            public static double SumItem(Func<int, DateTime, double> method, int startPeriodIncluded, int endPeriodIncluded, DateTime refinancingDate)
            {
                double sumItem = 0;
                for (int j = startPeriodIncluded; j < endPeriodIncluded + 1; j++)
                {
                    sumItem += method(j, refinancingDate);
                }
                return sumItem;
            }

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Tout dépend de ce que font les méthodes passées en paramètre.
    Mais, il est bizarre de voir une méthode statique attendre un pointeur de méthode.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    Bonjour,

    Vous trouverez ci-dessous les méthodes passées en paramètres. Ce sont de simples calculs de dates. Oui, j'apprends sur le tas et j'ai bien conscience que mon code doit contenir beaucoup de choses peu orthodoxes...

    Bien à vous,




    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public virtual DateTime PeriodDate(int p)
            {
                return DateTimeUtils.PeriodDate(this, p);
            }
     
    public virtual DateTime PeriodDate(int p, DateTime refinancingDate)
            {
               return DateTimeUtils.PeriodDate(this, p, refinancingDate);
            }
    Elles appellent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    static public DateTime PeriodDate(FinancialInstrument financialInstrument, int p)
            {
                DateTime issueDate = DateOnly(financialInstrument.IssueDate);
                int fiFrequency = financialInstrument.FiFrequency; 
                return issueDate.AddMonths(p * fiFrequency);
            }
     
    static public DateTime PeriodDate(FinancialInstrument financialInstrument, int p, DateTime refinancingDate)
            {
                int totalNbOfPeriods = financialInstrument.TotalNbOfPeriods;
                DateTime nDate = PeriodDate(financialInstrument, totalNbOfPeriods);
                DateTime pDate = PeriodDate(financialInstrument, p);
                DateTime refiDate = DateOnly(refinancingDate);
     
                if (refiDate <= nDate)
                {
                    if (pDate < refiDate & pDate < nDate)
                    {
                        return pDate;
                    }
                    else
                    {
                        return refiDate;
                    }
                }
                else
                {
                    return pDate;
                }
            }

  4. #4
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    En ne faisant qu'une seule méthode static PeriodDate prenant un Nullable<DateTime> tu devrais pouvoir n'avoir qu'une seul méthode virtuelle PeriodDate avec un Nullable<DateTime> et donc un seule méthode SumItem avec un Nullable<DateTime>.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    static public DateTime PeriodDate(FinancialInstrument financialInstrument, int p, Nullable<DateTime> refinancingDate)
    {
         if (refinancingDate.HasValue) 
        {
     
                int totalNbOfPeriods = financialInstrument.TotalNbOfPeriods;
                DateTime nDate = PeriodDate(financialInstrument, totalNbOfPeriods);
                DateTime pDate = PeriodDate(financialInstrument, p);
                DateTime refiDate = DateOnly(refinancingDate.Value);
     
                if (refiDate <= nDate)
                {
                    if (pDate < refiDate & pDate < nDate)
                    {
                        return pDate;
                    }
                    else
                    {
                        return refiDate;
                    }
                }
                else
                {
                    return pDate;
                }
          }
          else
         {
                DateTime issueDate = DateOnly(financialInstrument.IssueDate);
                int fiFrequency = financialInstrument.FiFrequency; 
                return issueDate.AddMonths(p * fiFrequency);
         }
     }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public virtual DateTime PeriodDate(int p, Nullable<DateTime> refinancingDate)
    {
         return DateTimeUtils.PeriodDate(this, p, refinancingDate);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            public static double SumItem(Func<int, Nullable<DateTime>, double> method, int startPeriodIncluded, int endPeriodIncluded, Nullable<DateTime> refinancingDate)
            {
                double sumItem = 0;
                for (int j = startPeriodIncluded; j < endPeriodIncluded + 1; j++)
                {
                    sumItem += method(j, refinancingDate);
                }
                return sumItem;
            }

  5. #5
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Je ne sais pas exactement ce à quoi correspond ton code, mais je me demande si tu ne réécrits pas des choses qui existent déjà sur les dates.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    @popo : merci je vais tester ça. Je pensais que le Delegate pouvait m'apporter une solution, mais de ce que j'en comprends, ça fonctionne comme un Func<>, donc a priori non

    @Noxen : c'est possible, ça ne m'étonnerait pas. Comme dit, j'apprends sur le tas... Pourrais-tu expliciter que je comprenne l'erreur potentielle ?

  7. #7
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Avec DateTime et TimeStamp tu as des méthodes pour faire des calculs sur les dates et les durées : ajouter ou retirer des jours, des mois, des heures, calculer la durée entre deux dates, etc... Mais comme je l'ai dit je ne sais pas si c'est tout ce dont tu as besoin.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    En fait j'ai copié collé les mauvaises fonctions... Les PeriodDate ne sont pas appelées dans le cadre de cette fonction, mais d'autres fonctions suivant le même principe et retournant des doubles.

    Est-ce que l'utilisation de Delegate peut me permettre de résoudre mon problème de "redondance de code" ?

  9. #9
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Les delegates permettent d'éviter la duplication lorsque tu as un algorithme de haut niveau pour lequel on veut pouvoir substituer l'une des composante ; c'est ce que tu as avec toutes les méthodes d'extension Linq ou bien la méthode List<T>.ForEach(Action<T>). Mais en principe tous les delegates concernés respecteront la même signature, donc il ne sera pas possible d'avoir différents nombre de paramètres.

    Par contre une méthode pourrait admettre des paramètres dont l'un aurait disposerait d'une valeur "idem potente" (par exemple le 0 pour des nombres). Mais en général on fait des méthodes spécialisés pour des questions de lisibilité. Et puis tout dépend de ce que tu appelles une redondance, si tu as besoin de différents nombre de paramètres cela peut correspondre à différents contextes et ce n'est pas forcément de la redondance.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    Qu'est ce qu'il faut entendre "algorithme de haut niveau" et "valeur "idem potente" "?

    Ce que j'appelle redondance c'est par exemple dans ma fonction SumItem le fait que la boucle est strictement la même. Si je devais changer la logique de la boucle, je devrais la changer dans les 2 fonctions.

    Ici ce n'est qu'un exemple, mais mon code comporte beaucoup de redondances de ce type que j'essaie de réduire au fur et à mesure. J'imaginais que l'emploi de Delegate pouvait m'aider. Le Nullable<T> me semble une bonne solution, mais je n'ai pas encore eu le temps de tester.

  11. #11
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Le DateTime est fixé dès le début et n'intervient pas dans la méthode, du point de vue de la méthode qu'il existe ou pas revient au même. Autant donc le fixer en amont à l'aide d'une closure et le problème est réglé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SumItem(n => methodWithDate(n, refinancingDate), startPeriodIncluded, endPeriod
    On peut bien sûr, stocker la lambda dans une variable locale en amont au besoin.
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    @Sehnsucht : désolé mais je n'ai pas compris... peux-tu s'il te plait expliciter ?
    @popo : j'ai essayé de changer avec un Nullable<DateTime>, mais le problème est que je ne vois pas l'intérêt. Finalement cela ne simplifie pas vraiment le code, cela met tout dans une seule fonction, mais on doit quand même avoir un if... else... qui reprendra les mêmes algorithmes que précédemment.

  13. #13
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Je vois pas vraiment quoi expliquer de plus que ce que j'ai déjà dit, surtout que je donne le code qui répond à la question initiale ; comment n'avoir qu'une surcharge et pouvoir l'utiliser avec le délégué qui a le DateTime quand même.
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 35
    Points : 22
    Points
    22
    Par défaut
    Je ne comprends pas ce que l'utilisation de la closure telle que décrite va différer d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Func<int, DateTime, double> method

  15. #15
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Elle ne diffère pas, elle permet de l'utiliser directement avec la surcharge de SumItem qui attend un Func<int, double>, et donc de n'avoir plus besoin que d'une surcharge (ou en avoir 2 avec la seconde déléguant à la première) ; comme dit dans mon message précédent
    Citation Envoyé par Sehnsucht Voir le message
    je donne le code qui répond à la question initiale ; comment n'avoir qu'une surcharge et pouvoir l'utiliser avec le délégué qui a le DateTime quand même.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //utilisation directe
    DateTime refinancingDate = …
    Func<int, DateTime, double> methodWithDate = (i, dt) => …
    Func<int, double> methodWithDateFixed = i => methodWithDate(i, refinancingDate);
    SumItem(methodWithDateFixed, …);
     
    //Surcharge qui délègue
    public static double SumItem(Func<int, DateTime, double> method, int startPeriodIncluded, int endPeriodIncluded, DateTime refinancingDate)
        => SumItem(i => method(i, refinancingDate), startPeriodIncluded, endPeriodIncluded);
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

Discussions similaires

  1. Comment simplifier mon code javascript?
    Par Nighthawk dans le forum jQuery
    Réponses: 2
    Dernier message: 15/07/2015, 10h15
  2. Comment simplifier ce code en une fonction simple ?
    Par roleca dans le forum Langage
    Réponses: 10
    Dernier message: 05/09/2014, 17h31
  3. comment simplifier ce code ?
    Par laurentSc dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 09/09/2013, 19h38
  4. [XL-2007] Comment simplifier mon code VBA SVP?
    Par anthooooony dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 20/02/2012, 10h59
  5. Réponses: 4
    Dernier message: 10/05/2008, 12h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo