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 :

Problème avec generic et appel de méthode


Sujet :

C#

  1. #1
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut Problème avec generic et appel de méthode
    Bonjour,

    je veux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class Essai<T>
    {
        Essai()
        {
            T t;
            T.TryParse( "2.3", t );
        }
    }
    Sachant que tous mes T auront une méthode TryParse (par exemple Essai<long>, Essai<DateTime>)

    J'ai l'erreur 'T' is a 'type parameter', which is not valid in the given context.

    Comment faire ? Merci.

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Points : 661
    Points
    661
    Par défaut
    deux erreurs :

    les contraintes sur ton type T!
    l'appel de tryparse qui etais fais avec T et non t!

    il faudra aussi penser à instancier ton objet t dans ton exemple !
    ca va te faire un nullrefexecption sinon.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class Essai<T> where T : InterfaceQuiImplementTryParse, new()
    {
        Essai()
        {
            T t = new T();
            t.TryParse( "2.3", t );
        }
    }
    Pour les details, cherche tout seul !

  3. #3
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Salut et merci pour ta réponse, mais on écrit bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DateTime date;
    DateTime.TryParse( "2.3", out date );
     
    // Ou alors
    long l;
    long.TryParse( "2.3", out l );
    Ma seule erreur (hormis l'erreur que m'a donné visual plus haut) c'est d'avoir oublié le mot clef out dans l'appel à TryParse.

    Mon exemple ne teste pas le retour de l'appel qui pourtant échouerait dans les deux cas, mais c'est juste un exemple.

    J'avais pensé à la contrainte ITryParse mais DateTime et long n'utilisent pas d'interface pour cette méthode et je ne veux pas avoir à utiliser un wrapper.

    En C++ ce que je veux faire est possible mais en C# je doute.

  4. #4
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Comment faire ? Merci.
    C'est simple : tu peux pas, parce que TryParse est une méthode statique, et que rien ne relie plusieurs types qui ont une même méthode statique.
    C'est un bon exemple de ce qui distingue les generics C# des templates C++ ; les uns se basent en partie sur la POO pour déterminer statiquement si le code est correct, les autres sont des macros au typage faible.
    ಠ_ಠ

  5. #5
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    ok c'est bien ce qui me semblait.

    Je pense que je peux m'en sortir par la reflexion cependant.

    Une remarque HS : je ne crois pas qu'on puisse qualifier les templates C++ de typage faible. Les templates permettent justement de renforcer le typage face et de vieilles habitudes comme les void*. Les generics C# ont cependant un typage encore plus fort, ce qui ne m'arrange pas trop d'ailleurs, mais je suppose qu'il y a des contraintes techniques derriere celà.

  6. #6
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Une remarque HS : je ne crois pas qu'on puisse qualifier les templates C++ de typage faible.
    Ce que je voulais dire, c'est que quand on écrit un template de méthode sur un type T, on a aucune information sur ce type T. je me souviens plus de la syntaxe exacte, mais on peut écrire en C++ un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<typename T> T Add(T t1, T t2) { return t1 + t2; }
    Et c'est après, si on appelle Add sur un type qui n'a pas d'opérateur +, qu'une erreur de compilation (bien indigeste, d'ailleurs, vivement C++0x et sa jolie syntaxe) apparaît. Alors qu'avec les generics et leurs contraintes (mot-clé where), une méthode générique valide est valide tout le temps.

    Je sais pas si je me fais bien comprendre mais je fatigue
    ಠ_ಠ

  7. #7
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Oui on est d'accord sur tous ces points. C'est juste que ça m'écorche l'oreille droite d'entendre que les templates C++ font du typage faible

    Les erreurs de type (bien indigestes pour un novice je te l'accorde) sont bel et bien détectées à la compil, donc -> typage fort.

    Maintenant il y a fort et FORT et C# c'est plutôt FOOOORT tu vois ce que je veux dire ?

  8. #8
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Maintenant il y a fort et FORT et C# c'est plutôt FOOOORT tu vois ce que je veux dire ?
    Bah disons que typage fort / faible est pas une expression super précise à la base Tu peux faire du code cradingue en C++ avec des dynamic_cast et reinterpretcast de partout qui court-circuitent le modèle objet de la syntaxe C++. Alors que C# ne traine pas le boulet du C et peut limiter les conversions de type sauvages.

    Mais bref, on est d'accord
    ಠ_ಠ

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    C'est vrai, tu peux faire des casts bizares en C++, mais C# aussi a les même problèmes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long l = (long)(object)new DateTime();
    Ce code ne donnera une erreur qu'à l'éxécution.

    Si on veut revenir au sujet qui sont les generics, ils permettent à mon sens une meilleure compréhension de l'utilisateur de la classe, qui sait quel type d'objets il doit fournir, mais du coup on perd en flexibilité.

  10. #10
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Ce code ne donnera une erreur qu'à l'éxécution.
    Ca tombe bien, c'est ce qu'on veut ! Heureusement qu'on peut faire du downcast quand même
    Ce que je veux dire, c'est qu'en C++, avec les casts qui vont bien, tu dois pouvoir convertir un (Type1 *) en (Type2 *) et te servir de la zone mémoire que t'avais allouée comme étant Type1 comme si c'était un Type2. Même s'il n'y a pas de lien d'héritage entre les deux. En C#, c'est impossible, tu peux pas "réinterpréter" une zone mémoire. (p't'êt en code unsafe, mais j'ai jamais eu besoin de tester )
    ಠ_ಠ

  11. #11
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par Guulh Voir le message
    (p't'êt en code unsafe, mais j'ai jamais eu besoin de tester )
    Effectivement, il faut passer par du code non managé. Par rapport au C++, ça a le gros avantage de prévenir l'utilisateur que ce qu'il fait risque de lui péter à la tronche (ou plutôt de corrompre sa mémoire sans qu'il s'en aperçoive). Du coup un développeur C# débutant préfèrera ne pas y toucher et c'est un bon point.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    unsafe
    {
        long l = new long();
        DateTime* dt = (DateTime*)&l;
        MessageBox.Show( dt->Date.ToString() );
    }
    Même si c'est beaucoup plus simple de se tromper en C++, j'avoue avoir rarement besoin de faire des reinterpret_cast et même des cast sur les pointeurs (hormis pour de l'optimisation poussée ou bien pallier à des incohérences des MFC ou de Win32).
    Les static_cast et dynamic_cast sont en général les plus utilisés et sûrs d'utilisation.

Discussions similaires

  1. Problème avec procédure stockée appelée via dblink
    Par SelectEtoile dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 24/01/2011, 16h45
  2. Réponses: 4
    Dernier message: 19/07/2009, 13h51
  3. Réponses: 1
    Dernier message: 10/10/2008, 10h50
  4. problème avec les variables de la méthode GET
    Par will97 dans le forum Langage
    Réponses: 11
    Dernier message: 11/12/2007, 14h43
  5. Problème avec les classes et les méthodes abstract
    Par BOLARD dans le forum Langage
    Réponses: 5
    Dernier message: 22/09/2007, 20h27

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