salut:
peut on faire :
List<ref maclass> malist;
Version imprimable
salut:
peut on faire :
List<ref maclass> malist;
Non, et ça n'aurait pas vraiment de sens. C'est dans des méthodes qu'on peut passer des paramètres par référence. Que cherches-tu à faire ?
utiliser une liste sans la copié
Les listes sont des types références, donc l'objet liste est lui-même passé par référence, il n'y a pas de copie si tu ne la fais pas toi-même.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 static void Main(string[] args) { var list = new List<string>(); Console.WriteLine(list.Count); // 0 AddItems(list); Console.WriteLine(list.Count); // 3 } static void AddItems(List<string> listParam) { listParam.Add("a"); listParam.Add("b"); listParam.Add("c"); }
question pas très claire
si tu as une list contenant 800 objets, en fait ce sont 800 pointeurs vers les objets que tu as dedans (un pointeur étant 32 ou 64bits)
et il y a 800 objets en mémoire ailleurs
si tu fais
ici seul le pointeur de la list est recopié (donc moins de 10 octets)Code:
1
2 var a = new list<object>(); // + 800x .Add() var b = a;
si tu fais une copie de la list (basiquement avec .ToList() ou moins basiquement avec plein d'autres choses) ce sont les 800 pointeurs qui sont copiés
mais ca a l'avantage de pouvoir traiter indépendamment les 2 collections
dans certains cas pour éviter une recopie de x pointeurs pour obtenir tout ou partie d'une collection il y a le type Span<T> qui doit se trouver en package nuget, j'ai cru comprendre qu'il n'était pas réservé à .net Core
merci,
donc :
1-ref n'est pas un type
2-une collection peut etre réferencée par son nom sans recopier les Datas qui y sont stockés.
3- Span<int> span = mylist=list<object>();
4-pourquoi on dit : il n' y a pas de comparaison avec les pointeurs en C++
1 non ref est un mot clé qu'on peut mettre devant un paramètre d'une méthode pour ne pas copier la valeur/le pointeur (selon si c'est un type par valeur ou un type par référence) mais récupérer le pointeur directement
2 en gros oui, comme tout objet (pas valable pour ce qui fonctionne par valeur) quand on dit a = b ce n'est que le pointeur qui est recopié
3 hein ?? je pense pas …
4 pas sur d'avoir compris mais en C et C++ un pointeur est une adresse mémoire, en .net un pointeur est un pointeur vers un pointeur ^^
(en c# avec du code unsafe on peut avoir manipuler les adresses mémoires comme en C, en vb.net il faut passer par du mashall je crois et ca permet moins de choses)
concernant les types par valeur et les types par référence :
les types valeurs sont les types de base (int, bool, datetime, bool, string, struct ...) ils sont alloués sur la pile (une partie de la mémoire réservée par l'appli)
et désalloués en sortie de portée
les types par références c'est tout le reste qui hérite de objet (toute classe hérite de object même quand on ne le précise pas)
ils sont alloués sur le tas (une autre partie de la mémoire) et désalloués par le garbage collector à l'occasion (et quand ils ne sont plus utilisés seulement)
types par valeur :
Code:
1
2
3 int a = 5; // a est un pointeur vers un espace mémoire contenant 5 b = a; // b est un pointeur vers un autre espace mémoire et a est copié dedans b = b + 1; // ici b vaudra 6 et a reste à 5
Code:
1
2
3
4
5
6
7
8
9 public int fctadd(nb int) // sans précision c'est une copie de la valeur qui sera placée dans nb { nb += 1; return nb; } var a = 5; var b = fct(a); // ici b vaut 6 et a 5;
Code:
1
2
3
4
5
6
7
8
9 public int fctadd(ref nb int) // ref fait que c'est le pointeur vers la variable qui sera copié comme pointeur de nb { nb += 1; return nb; } var a = 5; var b = fct(ref a); // ici b vaut 6 et a 6;
types par référence :
Code:
1
2
3
4
5 public class A { public int Nb {get;set;} = 5; public int Nb2 {get;set;} = 0; }
Code:
1
2
3
4
5 A a = new A(); // a est un pointeur vers un espace mémoire de la pile contenant un pointeur vers un espace mémoire du tas contenant une instance de A b = a; // b est un autre pointeur dans la pile contenant un pointeur vers le même espace mémoire du tas (donc la même instance) b.Nb = b.NB + 1; // ici b.Nb vaudra 6 mais a.Nb aussi car c'est la même instance d'objet qui est pointé par les 2 b = null; // a pointe toujours vers l'instance de A qui avait été crée a = null; // l'instance pointée vers a et b n'est plus pointée par personne, elle sera garbage collectée plus tard automatiquement
Code:
1
2
3
4
5
6
7
8
9
10
11 public A Add30(A ai) // sans précision c'est une copie du pointeur qui est placé dans ai { var nb = ai.Nb; ai.Nb2 += 1; ai = new A(); ai.Nb = nb; return ai; } var a = new A(); var b = Add30(a); // ici b vaut une instance de A ayant 35 en Nb mais a contient toujours l'instance de A qui avait 5
(dans les 2 cas a.Nb2 vaut 1)Code:
1
2
3
4
5
6
7
8
9
10
11 public A Add30(ref A ai) // avec ref ai est une copie du pointeur qui contient le pointeur vers l'instance { var nb = ai.Nb; ai.Nb2 += 1; ai = new A(); ai.Nb = nb; return ai; } var a = new A(); var b = Add30(a); // ici a et b pointent vers la même instance car on changé l'instance de a dans la méthode
(sur les explications je suis peut etre pas totalement exact avec les pointeurs, mais sur le fonctionnement les exemples sont bons)
pas mieux
mais pour utiliser des T c'est du côté des generics qu'il faut regarder
peuvent être déclarés génériques des classes ou des méthodes
à partir de là on peut récupérer le ou les types génériques pour les utiliser en tant que Tx
après quand on ne sait pas ce qu'on manipule ou qu'on veut mixer des choses avec List<object> on peut tout mettre dedans