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 :

[3.5] Class<T> adapter une méthode en fonction de T


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    CUCARACHA
    Invité(e)
    Par défaut [3.5] Class<T> adapter une méthode en fonction de T
    Salut,

    Je travaille sur un composant qui permet de définir des périodes.
    Les paramètres d'entrée sont :

    Propriété Debut (soit un int, soit une DateTime : T)
    Propriété Duree toujours un int

    en sortie on a une propriété Fin (soit un int, soit une DateTime : T)

    dans le cas où mon type générique est int

    Fin = Debut + Duree
    dans le cas du DateTime
    Fin = Debut.AddDays(Duree)

    J'essaye de câbler ma propriété publique Fin et c'est là que je suis à cours de matière grise

    si j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            public T Fin { 
                get {
                    if (typeof(T) == typeof(DateTime)) { 
                        //Fin = ((DateTime)Debut).AddDays(Duree); MARCHE PAS
                    }
     
                ;} 
            }
    C'est possible d'accéder aux méthodes de l'instance en fonction du type ?

    Merci

    Laurent
    Dernière modification par tomlev ; 03/12/2009 à 23h37. Motif: balises code

  2. #2
    Membre chevronné Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Par défaut
    Salut,
    sinon tu peux faire une classe de base non générique qui ne prend que que des entiers, et dans le code client récupérer une structure DateTime à partir de sa représentation numérique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //multiplié par 1000 (voire plus), en imaginant que la date est stockée en unités //de 1000 Ticks, à cause de la taille réduite de int par rapport à long
    var maDate = DateTime.FromFileTime((long)monInstance.Fin * 1000));
    Ou encore, dans le même esprit, créer une classe de base non générique qui expose une propriété Fin de type int, et une méthode à surcharger pour effectuer l'addition de la durée.

    Ou encore encore, deux classes différentes. Car de toute manière, ce qui me choque un peu c'est d'avoir une classe générique qui n'accepte que deux types conceptuellement, alors que techniquement tu ne peux pas restreindre les paramètres de type de cette manière (au mieux une contrainte sur struct, ou une interface du genre IComparable, IEquatable etc...).

    Ton exemple le montre bien : dès lors que l'on se retrouve à tester la valeur de T dans une classe générique, c'est qu'il y a un problème de conception (à mon sens).

  3. #3
    CUCARACHA
    Invité(e)
    Par défaut Bon j'ai fini par trouver une solution
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
        public class Period<T>
        {
            public T Debut { get; set; }
            public int Duree { get; set; }
            public T Fin
            {
                get
                {
                    if (typeof(T) == typeof(DateTime))
                    {
                        T fin = (T)CalculFin(Debut as DateTime?, Duree);
                        return fin;
                    }
                    else if (typeof(T) == typeof(int))
                    {
                        T fin = (T)CalculFin(Debut as int?, Duree);
                        return fin;
                    }
                    else
                    {
                        throw new Exception("Type non supporté");
                    }
                }
            }
     
            private object CalculFin(int? debut, int duree)
            {
                if (debut.HasValue)
                {
                    return debut.Value + this.Duree;
                }
                else
                {
                    return null;
                }
            }
            private object CalculFin(DateTime? debut, int duree)
            {
                if (debut.HasValue)
                {
                    return debut.Value.AddDays(this.Duree);
                }
                else
                {
                    return null;
                }
            }
            public Period(T debut,int duree)
            {
                this.Debut = debut;
                this.Duree = duree;
            }
        }
    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
     
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }
     
            protected void cmdOk_Click(object sender, EventArgs e)
            {
                CultureInfo Culture = new CultureInfo("fr-fr");
                int intDeb = -1;
                int duree = 0;
                int.TryParse(txtDuree.Text, out duree);
                DateTime dteDeb = new DateTime();
                if (int.TryParse(txtDebut.Text, out intDeb))
                {
                    Period<int> Period = new Period<int>(intDeb, duree);
                    txtFin.Text = Period.Fin.ToString();
                }
                else if (DateTime.TryParse(txtDebut.Text,out dteDeb)) {
                    Period<DateTime> Period = new Period<DateTime>(dteDeb, duree);
                    txtFin.Text = Period.Fin.ToString("d", Culture);
                };
     
            }
        }
    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
     
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Maquettes._Default" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        Debut<asp:TextBox ID="txtDebut" runat="server"></asp:TextBox><br />
        Duree<asp:TextBox ID="txtDuree" runat="server"></asp:TextBox><br />
        fin<asp:TextBox ID="txtFin" runat="server" ReadOnly="true"></asp:TextBox><br />
        <asp:Button ID="cmdOk" runat="server" Text="Button" onclick="cmdOk_Click" />
        </form>
    </body>
    </html>
    Si on entre un int, ca calcule la somme avec la durée,
    si on entre une date ca lui ajoute la durée en jours.

    ++

    Laurent

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Si tu testes le type générique pour faire du spécifique en fonction de ce type, tu perds tout l'intérêt des génériques... En plus qu'est-ce qui se passe si je crée un Period<MaSuperClassePasPrévue> ?

    Tu ferais mieux de faire 2 classes séparées, ce serait plus clair et plus sûr

  5. #5
    CUCARACHA
    Invité(e)
    Par défaut
    Salut,

    En fait cette classe va s'intégrer dans un composant bien plus complexe. J'avais besoin de travailler deux cas d'utilisation et c'est la seule solution que j'ai trouvé.

    ++

    Laurent

Discussions similaires

  1. Adapter une transaction en fonction
    Par johan0510 dans le forum SAP
    Réponses: 23
    Dernier message: 07/02/2013, 11h48
  2. Réponses: 8
    Dernier message: 12/03/2009, 16h03
  3. Réponses: 4
    Dernier message: 27/06/2007, 13h38
  4. [Reflection] Exécuter une méthode donnée d'une classe
    Par schousso dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 03/06/2004, 10h35
  5. Réponses: 3
    Dernier message: 16/04/2004, 16h51

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