60

C'est pas faux, mais il me semble que les tutos traitent plus souvent du langage que des fonctionnalités de l'IDE qui ne sont en grande majorité que des moyens de gagner du temps à quelques exceptions près (comme WCF). Disons que je vois mal un tuto dire "aller dans le 3ième menu et choisissez la deuxième option pour continuer".
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

61

yup, c'est pas faux sur le principe Pen^2, mais SharpDevelop est pratiquement un clone en ce qui concerne toutes les fonctionnalités courantes, donc même par rapport à certains tutos, je m'y retrouve. smile

62

Oui concernant le texte c'est sûr que ça ne doit pas changer grand chose, mais il y a peut-être les assistants, les outils de déploiement, les éditeurs de GUI, etc.
Je ne connais pas l'outil en question, ce n'est qu'une remarque générale cheeky

63

[23/05/2016 21:05:32] <Folco> Comment fait-on une affectation d'objet en C# (genre MonObjet a = b;
) ? Il faut explicitement définir l'opérateur = ? J'y pense que maitenant, mais j'ai rien lu dessus.[23/05/2016 21:06:10] <Folco> Ou plutôt, faire un constructeur de recopie ? MonObjet a = new MonObject(b);
Autant les bouquins de C++ que j'ai insistent lourdement sur le constructeur de copie et l'opérateur d'affectation, autant j'ai rien vu passer là-dessus en C#.

Et je viens de lire ça dans un bouquin que j'attaque ajd :
Un type référence, à la différence d’un type valeur, doit être instancié grâce au mot clé new.
Ca veut dire qu'on ne peut pas avoir d'objet local ??
Dois-je comprendre que le MonObjet a = b; dont je parle dans le premier quote ne crée alors qu'une référence a, référençant le même objet que b, et ne créant pas de nouvelle instance de l'objet ?

edit -> si on peut écrire string s = "abcde";, c'est qu'on peut déclarer un objet en local... Du coup, que signifie exactement le = dans cette expression ? A gauche, j'ai une référence typée, à droite j'ai un argument de constructeur d'objet...

64

Folco (./63) :
Autant les bouquins de C++ que j'ai insistent lourdement sur le constructeur de copie et l'opérateur d'affectation, autant j'ai rien vu passer là-dessus en C#.
C'est normal, l'intérêt d'un langage avec garbage collector c'est de ne pas recopier les objets et laisser le GC s'occuper de leur gestion à ta place. Copier des objets est assez (très) rare normalement, mais si tu en as vraiment besoin je pense avoir vu plus souvent des méthodes "Clone()" que des constructeurs par copie.
Folco (./63) :
Ca veut dire qu'on ne peut pas avoir d'objet local ??
Non, en effet. Un objet sera toujours* alloué sur le tas, et un type valeur toujours sur la pile.
Folco (./63) :
Dois-je comprendre que le MonObjet a = b; dont je parle dans le premier quote ne crée alors qu'une référence a, référençant le même objet que b, et ne créant pas de nouvelle instance de l'objet ?
Exactement, et normalement c'est ce dont tu devrais avoir besoin 99% du temps. Copier un objet est coûteux**, et à partir du moment où tu paies le prix d'un garbage collector autant l'utiliser à fond et en profiter pour limiter les recopies d'objets.
Folco (./63) :
edit -> si on peut écrire string s = "abcde";, c'est qu'on peut déclarer un objet en local... Du coup, que signifie exactement le = dans cette expression ? A gauche, j'ai une référence typée, à droite j'ai un argument de constructeur d'objet...
Tu peux voir ton expression comme un raccourci d'écriture pour string s = new string("abcde");, et ta string (qui est un type référence) se retrouve bien sur le tas.

* : c'est presque vrai, à une exception près.
** : d'ailleurs MSDN recommande d'utiliser des value types (struct) pour les types simples sans héritage avec 4 champs ou moins (et si possible immutables) ; les types références (class) sont conseillés dans tous les autres cas.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

65

Merci beaucoup, tout s'éclaire. J'ai vu dans mon premier bouquin le stackalloc en effet, j'ai vu qu'on retrouve aussi tout ce qui est pointeur et déréférencement en unsafe, j'ai failli avoir peur. Mais bon, je suppose que c'est pour des usages très particuliers (genre adresses absolues de périphériques ou autres joyeusetés).

66

À noter que le type string est une exception: c'est un type classe traité comme un type struct

67

Ben non, c'est un type référence à part entière, pourquoi penses-tu qu'il est traité comme un type struct ? (il n'est ni alloué sur la pile ni assigné par copie)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

68

Zeph (./64) :
Folco (./63) :
Dois-je comprendre que le MonObjet a = b; dont je parle dans le premier quote ne crée alors qu'une référence a, référençant le même objet que b, et ne créant pas de nouvelle instance de l'objet ?
Exactement, et normalement c'est ce dont tu devrais avoir besoin 99% du temps. Copier un objet est coûteux**, et à partir du moment où tu paies le prix d'un garbage collector autant l'utiliser à fond et en profiter pour limiter les recopies d'objets.
Le problème, c'est que c'est un piège très vicieux dans ces langages (et c'est vrai quel que soit le langage de ce type: Java, Python, C#, VB.NET, VB classique etc.). Ça arrive très couramment qu'on modifie accidentellement un objet original quand on veut en fait modifier une copie. Ça m'est déjà arrivé (en Java) alors que je connais le problème depuis longtemps (depuis l'époque où j'ai fait du VB). Et j'ai à plusieurs reprises vu et corrigé cette erreur dans le code d'autrui. Et même le mot-clé const (ou final en Java), quand il existe, n'aide pas, parce qu'il protège seulement la référence et non pas l'objet lui-même. À mon avis, les pointeurs explicits (avec copie de l'objet interdite, cf. QObject) et/ou le partage implicit / copie à l'écriture (comme pour les classes de données de Qt) sont beaucoup plus intuitifs.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

69

Je sais pas si c'est mieux ou pas, mais comme tu dis Qt utilise à profusion ces mécanismes, et ya de grandes chances que je me vautre plus d'une fois, du moins au début grin

70

très couramment ? je n'ai pas souvenir avoir eu ce genre de bugs hum
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

71

./67 Me suis mal exprimé. string est un type référence, mais il est immutable:

str = "Hello world":
str = str.Replace("world", "void");

L'appel à Replace créée une nouvelle chaîne de caractères dans le pool interne de chaînes du programme.

De plus

a = "A";
b = "A";
if (a == b) Console.WriteLine("Yippeee");
est vrai, car les types strings sont comparés comme des types valeurs, et non des références.

Pour "cloner" des objets (copier, en gros), Il y a Object.Clone, qui est disponible sur tous les types objets (retourne un object, donc on débox le résultat en général). Je ne m'en suis jamais servi, et je suis même pas certain que ce soit du deep cloning

72

Warpten (./71) :
De plus

a = "A";
b = "A";if (a == b) Console.WriteLine("Yippeee");est vrai, car les types strings sont comparés comme des types valeurs, et non des références.
Alors ton code fonctionne parce que "==" sur les strings compare leurs valeurs, donc bien sûr ça donne le résultat attendu.

Mais j'imagine que tu voulais dire object.ReferenceEquals(a, b) et dans ce cas c'est dangereux comme code. Ça va marcher par chance la plupart du temps parce que le compilateur décide de factoriser les chaines identiques, mais tu ne devrais vraiment pas reposer sur ce comportement. De la même façon comme le type string est immutable la VM se permet beaucoup de choses pour économiser la mémoire, par exemple il me semble qu'un "substr" sur une grande proportion d'une chaine va partager le même espace mémoire au lieu de recopier le contenu. Mais de la même façon, tu ne dois pas supposer que ce comportement existe dans ton programme.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

73

Zeph (./72) :
Alors ton code fonctionne parce que "==" sur les strings compare leurs valeurs, donc bien sûr ça donne le résultat attendu.

C'est ce que je dis

74

Alors du coup je ne comprends pas ton message. Le type string est un type référence, il est immutable et son opérateur "==" est défini, ces trois choses sont vraies mais sans aucun rapport l'une avec l'autre ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

75

Kevin Kofler (./68) :
Ça arrive très couramment qu'on modifie accidentellement un objet original
#pascrayon#
flanker (./70) :
très couramment ? je n'ai pas souvenir avoir eu ce genre de bugs hum
pencil
Je ne crois pas que ça me soit jamais arrivé non plus.

76

Zeph (./74) :
Le type string est un type référence, il est immutable
Immutable, ça veut bien dire ça ? https://fr.wikipedia.org/wiki/Objet_immuable Ca veut donc dire qu'on peut pas modifier le contenu d'une chaine ? Est-ce que ça en fait un objet constant, au sens C++ ?
Je ne me suis pas encore penché sur cette classe.

77

Oui, c'est quasiment la même notion que "const" en C++ : ça veut simplement dire que tu ne peux pas modifier le contenu de l'objet.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

78

Merci bien. smile

79

flanker (./70) :
très couramment ? je n'ai pas souvenir avoir eu ce genre de bugs hum
Ça arrive pourtant très vite, genre:public class Foo { public int x; // public pour l'exemple, ce serait la même chose avec get/set } public class Bar { private final Foo myFoo; Bar() { myFoo = new Foo(); myFoo.x = 1; } Foo getMyFoo() { return myFoo; } } public class Baz { doSomething(Foo foo) { foo.x = 2; } } public class Toto { public static void main (String[] args) { Bar bar = new Bar(); Foo foo = bar.getMyFoo(); new Baz().doSomething(foo); // et vlan! // Maintenant, bar.myFoo a x == 2, et le code de Bar risque de foirer à fond. } }(cet exemple devrait compiler en Java si on crée les fichiers qu'il faut, peut-être même aussi en C#, je ne sais pas, mais en tout cas, le problème est le même en C#).

Ça arrive très vite dans du code pas entièrement trivial. La solution la plus sure (mais aussi la moins performante) est de cloner myFoo dans getMyFoo(). C'est malheureusement la seule manière de garantir l'encapsulation.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

80

peut-être que ça t'arrive très vite, personnellement je n'ai pas souvenir avoir déjà eu ce genre de bugs, je ne suis apparemment pas le seul (cf. Pen^2), donc je ne comprends pas ta généralisation.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

81

Zeph (./77) :
Oui, c'est quasiment la même notion que "const" en C++ : ça veut simplement dire que tu ne peux pas modifier le contenu de l'objet.
La différence, c'est qu'un objet immuable l'est dans tous les contextes (c'est une propriété de la classe), alors qu'un objet C++ peut être muable dans la classe (ou fonction etc.) à laquelle il appartient et const pour le reste du code (il suffit de le retourner avec le mot-clé const). Une classe C++ peut avoir des méthodes const et non-const, dont seules les premières sont utilisables dans un contexte const, en Java ou C#, toute la classe doit être immuable, ce qui restreint beaucoup les cas d'usage de cette construction.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

82

On peut "tricher" en c# en déclarant du readonly où il faut (ça ne devient assignable que dans le constructeur). Les conteneurs sont exclus puisqu'on ne les assigne pas, on ne fait que les remplir.

En plus à un moment readonly ralentissait le code: https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/

83

C'est vraiment dommage que C# ne propose pas quelque chose d'équivalent au "const" du C++ qui aide vraiment à avoir des API explicites. Le mot-clé readonly n'est pas suffisant pour la raison que donne Warpten, le mot-clé const existe mais ne veut pas du tout dire la même chose (c'est pour déclarer une valeur constante, remplacée à la compilation), du coup la seule solution consiste à faire à la main une interface qui n'expose que les méthodes en lecture seule, puis d'ajouter les méthodes qui fournissent l'écriture uniquement dans l'implémentation. Mais ça demande beaucoup plus de code sad
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

84

Warpten (./82) :
On peut "tricher" en c# en déclarant du readonly où il faut (ça ne devient assignable que dans le constructeur). Les conteneurs sont exclus puisqu'on ne les assigne pas, on ne fait que les remplir.
C'est la même chose avec final en Java, mais ce n'est pas suffisant. On ne peut pas rendre tout immuable, du moins pas sans devoir recopier des objets énormes de partout. Et si un objet représente une ressource externe muable, un objet immuable est une représentation pas du tout appropriée.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

85

Petite question sur les types nullables : ce sont des types valeurs boxés, non ? Parce que je ne vois pas comment un entier pourrait avoir une valeur particulière qui soit nulle.

Bon, puisque vous savez pas, je me réponds :
            int? i = 0;
            if (i is object) {
            	Console.WriteLine("C'est un objet");
            }
Le programme que j'ai élaboré a établi de manière formelle que i est un objet.
Voilà, comme ça vous saurez vous aussi. embarrassed

86

Non, en fait le nom de cette classe est très mal choisi, Nullable<T> est en fait un type valeur (qui ne peut donc jamais être null). Tu peux l'imaginer comme une union d'un champ de type "T" et un booléen qui indique si le champ "T" est défini ou non. Les méthodes sont surchargées pour que le test "== null" fonctionne, mais je trouve ça super trompeur, cette classe aurait du s'appeler "Option<T>" comme dans d'autres langages pour éviter les confusions.

Ton test passe parce que "object" est le type parent de n'importe quoi en C#, y compris les types valeur, donc il ne teste pas grand chose en fait smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

87

Erf, je croyais que c'était le parent de tous les types référence, mais pas des types valeur. Merci bien.

88

C'est un peu confus, à force de vouloir tout faire entrer dans le modèle objet ça déborde à quelques endroits smile

Le type object est le parent de tous les autres types, et le parent des types valeur est ValueType qui bien sûr hérite lui-même de object. Du coup tu peux écrire des choses comme object i = 3; qui fonctionne parce que int hérite de object, sauf que ça boxe. Et puis tu te retrouves avec une variable i qui vaut bien 3, mais dans laquelle tu pourrais aussi mettre null juste derrière sans que ça pose problème, alors qu'un int (qui hérite lui aussi de object) ne peut jamais être nul.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

89

Si tu veux un vrai Nullable/Option<T>.... https://github.com/louthy/language-ext smile

90

Jolie bibliothèque, je ne connaissais pas smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)