« List » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
(Une version intermédiaire par le même utilisateur non affichée) | |||
Ligne 96 : | Ligne 96 : | ||
= Covariance = | = Covariance = | ||
<kode lang='cs'> | <kode lang='cs'> | ||
List<B> | List<B> listB; // class B inherits of class A | ||
List<A> | List<A> listA = listB; // Cannot convert type List<B> to List<A> because there is no covariance with List<T> | ||
IList<A> | IList<A> listA = listB; // Cannot implicitly convert type List<B> to IList<A>. An explicit conversion exists | ||
var listA = (IList<A>)listB; // There is covariance with IList<T> | |||
IList<B> iListB; | |||
IList<A> iListA = iListB; // Cannot implicitly convert type List<B> to IList<A>. An explicit conversion exists | |||
var iListA = (IList<A>)iListB; // There is covariance with IList<T> | |||
IEnumerable<B> ieb = lb.Select(b => b); | IEnumerable<B> ieb = lb.Select(b => b); | ||
Ligne 118 : | Ligne 123 : | ||
var areNotEquals = !myList1.All(myList2.Contains); | var areNotEquals = !myList1.All(myList2.Contains); | ||
</kode> | </kode> | ||
[[LINQ# | |||
* [[LINQ#IEqualityComparer|IEqualityComparer]] | |||
* [[LINQ#IEquatable|IEquatable]] | |||
== IEquatable == | == IEquatable == |
Dernière version du 26 mars 2024 à 13:55
Initialiseur
var listInt = new List<int> { 4, 5, 6, 7 }; |
Méthode Find
static void Main(string[] args) { var liste = new List<DoubleInt>() { new DoubleInt() { int1 = 0, int2 = 1 }, new DoubleInt() { int1 = 1, int2 = 2 }, new DoubleInt() { int1 = 2, int2 = 3 } }; // L’intérêt du délégué est de pouvoir spécifié les valeurs du filtre // en dehors du délégué. int two = 2; var doubleInt = liste.Find( delegate(DoubleInt di) { return di.int1 == two; } ); var liste2 = liste.FindAll(ContainsOne); } static bool ContainsOne(DoubleInt di) { return (di.int1 == 1 || di.int2 == 1); } class DoubleInt { public int int1, int2; } |
Méthode Sort
class DoubleInt { public int int1, int2; } var liste = new List<DoubleInt>() { new DoubleInt() { int1 = 5, int2 = 1 }, new DoubleInt() { int1 = 2, int2 = 2 }, new DoubleInt() { int1 = 4, int2 = 3 } }; // Calling the Sort() method results in the use of the default comparer for the DoubleInt type // which is the IComparable.CompareTo method liste.Sort(); // System.InvalidOperationException: No IComparable<T> or IComparable interface found for type 'DoubleInt'. |
IComparable
class DoubleInt : IComparable<DoubleInt> { public int int1, int2; public int CompareTo(DoubleInt other) { return int1.CompareTo(other.int1); } } |
delegate int Comparison<in T>(T x, T y)
// delegate anonyme 1 liste.Sort( (di1, di2) => { return di1.int1.CompareTo(di2.int1); } ); // named function liste.Sort(CompareDoubleInt); static int CompareDoubleInt(DoubleInt di1, DoubleInt di2) { if (di1 == null) // if item1 is null { if (di2 == null) return 0; // and item2 is null, they're equal. else return -1; // and item2 is not null, item2 is greater. } else // if item1 is not null { if (di2 == null) return 1; // and item2 is null, item1 is greater. else // and item2 is not null : { return di1.int1.CompareTo(di2.int1); } } } |
Éliminer les doublons
Distinct
Requête LINQ
personnes.GroupBy(p => p.PersonId) .Select(g => g.FirstOrDefault()) .ToList(); |
Covariance
List<B> listB; // class B inherits of class A List<A> listA = listB; // Cannot convert type List<B> to List<A> because there is no covariance with List<T> IList<A> listA = listB; // Cannot implicitly convert type List<B> to IList<A>. An explicit conversion exists var listA = (IList<A>)listB; // There is covariance with IList<T> IList<B> iListB; IList<A> iListA = iListB; // Cannot implicitly convert type List<B> to IList<A>. An explicit conversion exists var iListA = (IList<A>)iListB; // There is covariance with IList<T> IEnumerable<B> ieb = lb.Select(b => b); IEnumerable<A> iea = ieb; // ok: covariance avec IEnumerable<T> IReadOnlyCollection<B> lbr = lb.AsReadOnly(); IReadOnlyCollection<A> lar = lbr; // ok: covariance avec IReadOnlyCollection<T> |
Tester si 2 List sont égales
// prend en compte l'ordre l'ordre des éléments bool areEquals = myList1.SequenceEqual(myList2); // sans prendre en compte l'ordre des éléments // il faut tester count, car retourne true si myList2 contient plus d'éléments que myList1 bool areEquals = myList1.Count == myList2.Count && myList1.All(myList2.Contains); var areNotEquals = !myList1.All(myList2.Contains); |
IEquatable
Si les éléments de la liste sont de type référence, il faut que ce type implémente IEquatable pour permettre la comparaison.
public class Item : IEquatable<Item> { public int Id { get; set; } public string Name { get; set; } // implémentation de IEquatable<Item> public bool Equals(Item other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return this.Id == other.Id && this.Name == other.Name; } // surcharge Equals public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return this.Equals((Item)obj); } // surcharge GetHashCode public override int GetHashCode() { unchecked { return (this.Id * 397) ^ this.Name.GetHashCode(); } } public static bool operator ==(Item left, Item right) { return Equals(left, right); } public static bool operator !=(Item left, Item right) { return !Equals(left, right); } |
LinkedList vs List
LinkedList est composé d'élément dont chacun pointe vers le précédent et le suivant (comme une chaîne). Il est donc peut coûteux d'ajouter ou de supprimer des élément. Mais l'accès à un élément nécessite le parcourt de la liste.
List est un wrapper autour d'un Array, l'ajout ou la suppression d'éléments peut nécessiter un redimensionnement du tableau interne. Mais l'accès à un élément se fait directement via son index.
ReadOnlyCollection
ReadOnlyCollection.cs |
// in the .NET framework public class ReadOnlyCollection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T> { // only a ctor with IList<T> public ReadOnlyCollection(IList<T> list) { /* ... */ } } |
ListExtensions.cs |
public static class ListExtensions { public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> list) => new ReadOnlyCollection<T>(list); } |
var myList = new List<string>; IReadOnlyCollection<string> roCollection = myList.AsReadOnly(); |
ICollection to IReadOnlyCollection
A class System.Collections.ObjectModel.CollectionExtensions already exists for the AddRange method |
CollectionExtensions.cs |
public static class CollectionExtensions { public static IReadOnlyCollection<T> AsReadOnly<T>(this ICollection<T> collection) => new ReadOnlyCollectionAdapter<T>(collection); // an adapter is required because the ReadOnlyCollection ctor takes only IList<T> private sealed class ReadOnlyCollectionAdapter<T> : IReadOnlyCollection<T> { private readonly ICollection<T> source; public ReadOnlyCollectionAdapter(ICollection<T> source) => this.source = source; public int Count => this.source.Count; public IEnumerator<T> GetEnumerator() => this.source.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); } // call the AddRange method of the System.Collections.ObjectModel.CollectionExtensions class public static Collection<T> AddRange<T>(this Collection<T> collection, IEnumerable<T> items) => System.Collections.ObjectModel.CollectionExtensions.AddRange(collection, items); } |
ICollection<string> myCollection = new List<string>; IReadOnlyCollection<string> roCollection = myCollection.AsReadOnly(); |