[C#] Questions de débutant...

Questions de débutant... [C#] - C#/.NET managed - Programmation

Marsh Posté le 17-06-2009 à 11:00:17    

Salut à tous,
 
Je débute en C# et je me pose quelques questions... J'ai regardé un peu sur le Net mais je n'ai jamais vraiment trouvé d'explications claires, je compte donc sur vous pour m'éclairer sur les points suivants :
 
1) Quelle est la différence entre :

Code :
  1. class toto
  2. {
  3.   Collection<string> macollec= new Collection<string>();
  4.   toto (string montexte)
  5.   {
  6.     macollec.Add(montexte);
  7.   }
  8. }

et  

Code :
  1. class toto
  2. {
  3.   Collection<string> macollec;
  4.   toto (string montexte)
  5.   {
  6.     macollec = new Collection<string>();
  7.     macollec.Add(montexte);
  8.   }
  9. }

2) Quelle est la différence entre Collection<T>, List<T>, ICollection<T>, IList<T> ?
Si vous avez une bonne source qui explique ça, ça m'interesse.
 
3) N'ayant pas connaissance des autres options j'étais parti sur des Collections et j'aurais aimer créer ma propre class Collection et y ajoutant des fonctions de recherche sur Name (car toutes mes classes ont un attribut Name), mais je n'arrive pas à faire un truc générique, comment faire :
(De mémoire car je n'ai plus mon code sous les yeux)

Code :
  1. class collec<T> : Collection<T>
  2. {
  3.   public T Name(string name)
  4.   {
  5.     foreach(T temp in this)
  6.     {
  7.       if(temp.Name == name)
  8.       {
  9.          return temp;
  10.       }
  11.     }
  12.     return default(T);
  13.   }
  14. }

Mais dans ce cas T.Name n'existe pas (logique) donc impossible de compiler.
 
En espérant que celà inspire certains d'entre-vous, merci d'avance pour vos réponses.

Reply

Marsh Posté le 17-06-2009 à 11:00:17   

Reply

Marsh Posté le 17-06-2009 à 11:30:12    

1/ Je ne saurais répondre, mise à part que dans le premier cas, l'allocation de mémoire pour l'objet liste se fait avant le déclenchement du contructeur. après aucune idée de l'impact, perso je préfère tout coller les déclarations dans le contructeur.

 

2/ Ixxxx c'est des interfaces. Donc d'entrée de jeu, c'est pas pareil que xxxx, qui est une classe, donc instanciable. Ensuite, entre Collection et List, c'est juste les méthodes qui sont différentes à l'intérieur. List est une liste chaînée. Collection est une collection, c'est à dire une sorte de array à dimension et indexation dynamique.
PS : Avec VS 2008, j'ai pas trouvé "Collection<T>", j'aiu peut-être mal cherché.

 

3/ Je passerait par une interface :

 
Code :
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace Test
  7. {
  8.    class Program
  9.    {
  10.        static void Main(string[] args)
  11.        {
  12.            collec<MaClasse> c = new collec<MaClasse>();
  13.            c.Add(new MaClasse("A", 1));
  14.            c.Add(new MaClasse("B", 2));
  15.            c.Add(new MaClasse("C", 4));
  16.            c.Add(new MaClasse("D", 8));
  17.  
  18.            Console.WriteLine(c.GetByName("C" ));
  19.            Console.ReadKey(true);
  20.        }
  21.    }
  22.  
  23.    public class MaClasse : INamedClass
  24.    {
  25.        public int value;
  26.        public string name;
  27.  
  28.        public MaClasse(string Name, int Value)
  29.        {
  30.            this.name = Name;
  31.            this.value = Value;
  32.        }
  33.  
  34.        public string GetName()
  35.        {
  36.            return name;
  37.        }
  38.  
  39.        public override string ToString()
  40.        {
  41.            return string.Format("{0}\t= {1}", name, value);
  42.        }
  43.    }
  44.  
  45.    public class collec<T> : List<T>
  46.    {
  47.        public T GetByName(string Name)
  48.        {
  49.            foreach (T el in this)
  50.            {
  51.                if ((el as INamedClass).GetName() == Name)
  52.                {
  53.                    return el;
  54.                }
  55.            }
  56.  
  57.            return default(T);
  58.        }
  59.    }
  60.  
  61.    public interface INamedClass
  62.    {
  63.        string GetName();
  64.    }
  65. }
 


Grmpf, grillé. le "where T : Ixxx" est plus joli effectivement que mon truc ^^

Message cité 1 fois
Message édité par MagicBuzz le 17-06-2009 à 11:31:17
Reply

Marsh Posté le 17-06-2009 à 11:32:11    

Merci pour cette réponse rapide, je n'ai pas les moyens de tester ça au boulot mais je m'y remets ce soir.
 
Entre temps je vais trainer sur le Net bien comprendre les Interfaces car je pense que c'est ça qui m'échappe.

Reply

Marsh Posté le 17-06-2009 à 11:32:11    

PS pour Harko : pourquoi cet empaffé de compilateur m'a refusé l'utilisation d'un filed dans une interface ??? J'ai été obligé de tout modifier pour utiliser une méthode GetName() à la place, ce qui est quand même moins sympa...

Reply

Marsh Posté le 17-06-2009 à 11:34:08    

Une interface, c'est un contrat que tu imposes à ton objet qui en hérite.
 
Ainsi, tu impose à ton objet, dans l'exemple d'Harko, d'avoir une propriété "string Name", et dans mon exemple, une méthode "string GetName()".
Contrairement à un héritage de classe, tu peux hériter d'autant d'interfaces que tu veux. Genre tu peux hériter de l'interface d'Harko et de la mienne si tu veux.

Reply

Marsh Posté le 17-06-2009 à 11:37:42    

MagicBuzz a écrit :

PS : Avec VS 2008, j'ai pas trouvé "Collection<T>", j'ai peut-être mal cherché.

System.Collections.ObjectModel ?
Pour ma part je suis sous C# Express (2005) et j'utilise le Framework 2.
 
En tout cas merci encore pour les réponses.
(Décidement ces interfaces, faut que je m'y mette :p)

Reply

Marsh Posté le 17-06-2009 à 11:38:50    

Moi j'utilise "using System.Collections.Generic;" ça doit être pour ça :)

Reply

Marsh Posté le 17-06-2009 à 13:02:25    

Ben j'ai du merder à priori, moi il me disait que j'avais pas le droit de mettre une proriété dans une interface :??: (je crois que c'est le terme property qui était utilisé)

Reply

Marsh Posté le 17-06-2009 à 13:15:55    

Correction : C'est bien de "field" qu'il est question :

 


Error 1 Interfaces cannot contain fields C:\Users\xxxxx\Documents\Visual Studio 2008\Projects\Test\Test\Program.cs 58 23 Test

 

http://img15.imageshack.us/img15/3937/interfacefield.png

 

(super la capture d'écran qui n'apporte rien... en fait, je suis en .NET 3.5 SP1 avec VS 2008 version "9.0.30729.4056 QFE" )


Message édité par MagicBuzz le 17-06-2009 à 13:17:50
Reply

Marsh Posté le 17-06-2009 à 13:20:27    

Ok, donc c'est une propriété qu'il faut :jap:
 
Bon, du coup c'est pas plus lourd avec mon exemple de GetName() :D

Reply

Marsh Posté le 17-06-2009 à 13:20:27   

Reply

Marsh Posté le 17-06-2009 à 13:29:13    

Code :
  1. string Name { get; set; }


c'est pas beaucoup plus lourd que

Code :
  1. string GetName();


(c'est pas exactement équivalent non plus: ça génère aussi un setter)

 

Message cité 1 fois
Message édité par masklinn le 17-06-2009 à 13:30:30

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 17-06-2009 à 13:39:30    

Ah mais ça j'ai pas dit le contraire ;)
 
Juste que vu que j'ai fais avec un GetName(), c'est pas spécialement utile de passer par une propriété à la place, surtout pour un exemple.
 
Après, il y a le pour et le contre de Setter sous forme de méthode ou de propriété.

Reply

Marsh Posté le 17-06-2009 à 13:40:47    

Fred82 > oups, depuis le début je te confond avec harko :D désolé ^^

Reply

Marsh Posté le 17-06-2009 à 14:20:25    

masklinn a écrit :

Code :
  1. string Name { get; set; }



Ce ne serait pas limité au framework 3 ce truc la ?
(Je parle de la synthaxe hein.)

Message cité 1 fois
Message édité par Twiddy le 17-06-2009 à 14:21:03
Reply

Marsh Posté le 17-06-2009 à 14:23:14    

Twiddy a écrit :

Ce ne serait pas limité au framework 3 ce truc la ?


Au framework non, au langage (C# 3.0) oui.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 17-06-2009 à 14:29:57    

masklinn a écrit :


Au framework non, au langage (C# 3.0) oui.


 
il me semble lavoir deja vu il y a quelques annés en c# 2, voir 1 (j'apppelais ca des attributs abstrait dans UML)


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 17-06-2009 à 14:31:02    

kadreg a écrit :

 

il me semble lavoir deja vu il y a quelques annés en c# 2, voir 1 (j'apppelais ca des attributs abstrait dans UML)


Il y avait des properties, mais pas les versions auto :)

 

Donc il fallait écrire ça:

Code :
  1. string name;
  2. string Name {
  3.    get { return name; }
  4.    set { name = value; }
  5. }
 

edit:
[:fail] voir en dessous, dans le cadre des interfaces kadreg a raison :o


Message édité par masklinn le 17-06-2009 à 14:44:29

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 17-06-2009 à 14:36:32    

Arf, je croyais que c'était un prototype le "string Name { get; set; }" :D

 

En fait, là il crée automatiquement le field privé + le getter et le setter ?

 

Si c'est le cas, ok, c'est carrément sympa comme raccourci !

Message cité 1 fois
Message édité par MagicBuzz le 17-06-2009 à 14:36:59
Reply

Marsh Posté le 17-06-2009 à 14:43:13    

MagicBuzz a écrit :

En fait, là il crée automatiquement le field privé + le getter et le setter ?


Après plus de recherches, c'est les deux en fait en fonction du contexte (et donc kadreg a raison dans le cadre d'une interface):

  • Dans une interface, ça déclare une property et son accessibilité ({get;} pour readonly, {set;} pour write-only et {get; set;} pour read-write) depuis ... longtemps (C# 1.0?)
  • Dans une classe, ça déclare une automatic property (depuis C# 3.0)


Légère confusion de ma part donc.


Message édité par masklinn le 17-06-2009 à 14:43:46

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 17-06-2009 à 15:05:36    

Remplacer :

Code :
  1. string Name;


 
Par :

Code :
  1. string Name { get; set; }


 
Ca n'a effectivement aucun intérêt. Tout du moins, si on n'y touche plus après.
Habituellement, on n'aime pas les field public (y'a d'ailleurs un langage objet qui l'interdit).
En C#, un field est géré en interne de toute façon comme une propriété avec un set et un get par défaut (donc ça n'a aucun intérêt d'un point de vue performance ou autre de le faire explicitement)
 
En revanche, pour l'évolution du code, faire une propriété, c'est s'accorder la possibilité plus tard de modifier le get ou le set (voir les deux) sans devoir modifier la moitié du code de l'application, et contrôler à 100% l'impact que ça peut avoir.

Reply

Marsh Posté le 17-06-2009 à 15:19:53    


  • Si tu commences par utiliser des champs publiques, il faut tout recompiler si tu veux en faire des properties (pas juste la classe définissant le field/la property, mais aussi tous les callers)
  • Le remplacement n'est pas transparent au niveau nommage, puisque les conventions C# sont camelCase pour les fields et PascalCase pour les properties (et methods)
  • Un field ne peut faire partie d'une interface


Si tu utilises des properties, tu peux les faire évoluer par la suite et tu peux les mettre dans des interfaces [:spamafote]

 

Les properties C# ne sont vraiment rien de plus que des getters/setters avec une syntaxe moins pourrie et (depuis 3.0) une déclaration triviale pour le cas dégénéré.


Message édité par masklinn le 17-06-2009 à 15:24:39

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 18-06-2009 à 11:42:38    

Afin de ne pas ouvrir un nouveau topic je poste ma nouvelle question ici :
 
J'ai une classe serialisable, je génère un fichier xml correspondant, j'ai un xls qui va bien. Mon but, sortir avec tout ça un fichier Word mis en page. Est-ce possible "simplement" ?
 
Merci d'avance.
 
Edit : j'ai peut-être trouvé http://www.codeproject.com/KB/offi [...] ports.aspx


Message édité par Twiddy le 18-06-2009 à 11:59:28
Reply

Marsh Posté le 23-06-2009 à 17:07:00    

J'ai une nouvelle question : dans une Form1 j'ai une liste de n objets, je souhaite que, lorsqu'on clique sur un objet, cela ouvre une seconde Form qui détaille l'objet en question. Pour cette partie, pas de problème particulier mais mon problème c'est que je veux qu'on ne puisse ouvrir qu'unê Form par objet. Donc si la Form de l'objet en queston existe déjà, je veux juste qu'elle repasse au premier plan.
 
Avez-vous une idée pour réaliser celà ?

Reply

Marsh Posté le 24-06-2009 à 15:21:12    

Merci pour cette réponse. Effectivement j'ai compris le principe, je vais essayer de le mettre en application. Pour tester si la Form existe, le plus propre c'est quoi if(maForm == nothing) ?

Reply

Marsh Posté le 24-06-2009 à 16:50:38    

:jap: Merci, faut que je regarde ça...

Reply

Marsh Posté le 26-06-2009 à 23:33:18    

Je suis en train de tester mais finallement ça ne correspond pas tout à fait à ce qu'il me faut...
 
L'idéal serait de gérer, au sein de l'application, une List<Form> et d'y ajouter/retirer au fur et à mesure les forms que j'ouvre et je ferme.

Code :
  1. private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
  2.         {
  3.             Form2 form2 = null;
  4.             foreach (Form curform in tab)
  5.             {
  6.                 if (curform.Text == listBox1.SelectedItem.ToString())
  7.                 {
  8.                     form2 = (Form2)curform;
  9.                 }
  10.             }
  11.             if (form2 == null)
  12.             {
  13.                 form2 = new Form2(listBox1.SelectedItem.ToString());
  14.                 tab.Add(form2);
  15.             }
  16.             form2.Show();
  17.             form2.Focus();
  18.         }

J'identifie par un nom, unique, mes forms (ok c'est crade, si vous avez mieux...). Mais comment gérer la List<Form> correctement pour qu'elle soit unique mais accéssible de toutes les forms ouvertes ?

Reply

Marsh Posté le 27-06-2009 à 09:57:39    

Le but c'est que j'ai une multitude d'objets différents, à chaque type d'objet je vais associer une FormX différente. Chacune des nouvelles form possèdera sa propre liste d'objet dont certains pourront être identiques à ceux de la liste principale. Donc chaque form devra permettre l'affichage d'un nouvelle objet mais chaque objet ne doit posséder qu'une form.
Le nombre d'objets étant important et variable, je pense qu'il est plus interessant de pouvoir ajouter/retirer un objet d'une collection plutôt que de gérer un tableau...
 
Qu'en penses-tu ?


Message édité par Twiddy le 27-06-2009 à 10:13:37
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed