Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#] Sorteren van een IList<T>

Pagina: 1
Acties:
  • 1.089 views sinds 30-01-2008
  • Reageer

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
Ik ben op zoek naar een manier om een type die IList<T> implementeert te sorteren, echter heb ik nog niets gevonden.

List<T> heeft een Sort method, maar de interface IList<T> heeft deze niet.

Via de methode ArrayList.Adapter(IList list).Sort kun je een IList sorteren, maar die accepteert geen IList<T>.

Ik heb aardig wat gezocht, maar ik kom er helaas echt niet uit. Misschien een suggestie die me op de goede weg helpt. Misschien wil ik IList<T> wel helemaal niet sorteren, maar weet ik gewoon niet waarom.

Noushka's Magnificent Dream | Unity


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Sort wordt op de List<T> klasse geimplementeerd. Dat je een IList<T> niet kunt sorteren via ArrayList is omdat ArrayList geen generic is.
Wat je wel kunt doen is zelf een "helper" te maken die een IList<T> accepteert en dan met IComparer<T> aan de slag gaan.

[ Voor 31% gewijzigd door MTWZZ op 30-11-2007 11:32 ]

Nu met Land Rover Series 3 en Defender 90


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Waarom inherit je niet van List<T>? Dat implementeer je in een keer de IList<T> interface en bovendien heb je de sort functionaliteit van List<T>?

[ Voor 8% gewijzigd door bigbeng op 30-11-2007 11:35 ]


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11 13:15

Korben

() => {};

IList<T> is niet de interface voor een 'sorteerbare lijst', dus is het inderdaad niet te sorteren. De vraag is waarom je voor IList<T> als basistype hebt gekozen en niet bijvoorbeeld List<T>, want die is wel sorteerbaar.

Een andere mogelijkheid is om je lijst niet alleen IList<T>, maar ook IList te laten implementeren. Dan is hij wel sorteerbaar met ArrayList.Adapter().

Als je lijst intern een array gebruikt is het natuurlijk handig om hetzelfde te doen als wat List<T> intern doet: Array.Sort<T>() gebruiken.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • EfBe
  • Registratie: Januari 2000
  • Niet online
List<T> gebruiken, generic interfaces zijn sowieso niet nuttig. Een interface is een manier van generic programming, maar wanneer de interface generic is, heb je een probleem vaak want wat is T?

List<T> is met Sort in 1 regel te sorteren mbv een anonymous method

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
Even voor de duidelijkheid, ik heb zelf geen custom lijst of iets dergelijks. Dus ik implementeer IList<T> helemaal niet. Ik heb echter een Utility class die bewerkingen uitvoert op typen die een bepaalde zelf gedefinieerde interface implementeren. Een aantal bewerkingen worden ook op een lijst van dat type uitgevoerd.

Nu wil ik het zo flexibel mogelijk maken en programmeer best practices toepassen. Een van die principes is dat je liever niet afhankelijk wilt zijn van een class, maar liever van een interface als deze er is. Er is dus een List, maar dit is een class, terwijl IList een interface is.

Ik kan natuurlijk wel alleen List objecten accepteren, maar dan is het minder flexibel en minder beschermt tegen wijzigingen.

Wat ik me bij die helper moet voorstellen is me nog niet helemaal duidelijk. Misschien heb je een voorbeeld?

Noushka's Magnificent Dream | Unity


  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Je moet soms een beetje pragmatisch zijn ook ....
Daarmee bedoel ik, waarom zou je in dit geval tegen IList<T> programmeren ipv tegen List<T>. Welke voordelen heb je nu door tegen IList<T> te programmeren ? Heb je het nu nodig om zo generiek te zijn ?

https://fgheysels.github.io/


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
Ik het niet nodig nee. :P

Ik snap je punt wel, maar ik was gewoon benieuwd of IList<T> ook gemakkelijk te sorteren was. Als het te veel moeite is, dan ga ik wel tegen List<T> programmeren, dat is het probleem niet. De naamgeving is gewoon een beetje verwarrend. Bij IList zou je verwachten dat deze alle methoden List heeft, aangezien de namen overeenkomen. Dit blijkt echter niet zo te zijn.

Waarom niet is me nog niet helemaal duidelijk alleen. Eveneens niet waarom IList<T> niet te sorteren is.

Noushka's Magnificent Dream | Unity


  • EfBe
  • Registratie: Januari 2000
  • Niet online
IList<T> is niet te sorteren omdat sorteren niet een mandatory operatie is van een list, dus een class die IList<T> implementeert HOEFT nu niet te sorten. Zou je sort opnemen in de interface dan moet die class dus ook kunnen sorteren, wat niet altijd nodig hoeft te zijn.

Verder, als je generiek bezig wilt zijn, werk je met IList, en niet IList<T>, want je hoeft dan at compile time niet T te definieren en wellicht is T niet duidelijk at compile time.

List<T> implementeert IList maar IS niet identiek aan IList, daarom is de interface er ook. List is EEN implementatie van IList, maar heeft daarnaast ook eigen methods.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Ik ben niet bekend met de C# generics syntax, dus ik doe het even in C++. Kun je niet zoiets doen en gewoon verwachtten dat een Sort method aanwezig is?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename T>
void do_stuff(const T &a_List){
   a_List.Sort();
}

class SomeList{
public:
    void Sort();
};

class OtherList{
public:
    void Sort();
};

SomeList l_List;
do_stuff(l_List);

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 29-11 15:35
Dit geen idee?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ToStringComparer : IComparer
{
   public int Compare(object x, object y)
   {
   return ((FieldEngine)x).FieldName.ToString().CompareTo(((FieldEngine)y).FieldName.ToString());
   }
}

public IList<FieldEngine> SortIList(IList<FieldEngine> list)
{
   ArrayList.Adapter((IList)list).Sort(new ToStringComparer());

   return list;
}

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 05-11 19:33
@EfBe:
Dat klinkt inderdaad wel logisch. Maar een interface kan zeker wel identiek zijn aan de class. Zeker in het geval van frameworks wil je de optie soms openlaten voor alternatieve implementaties, zonder dat je met een concrete class hoeft te gaan werken. Vanwege de overkomst in namen van List en IList had ik verwacht dat ze wat meer gerelateerd zouden zijn, maar kennelijk zijn het toch 2 totaal verschillende abstracties.

Verder is in dit geval T zeker wel bekend. T is juist de belangrijkste schakel in het geheel. De Utility class is er namelijk speciaal om daar handelingen op uit te voeren.

@PrisonerOfPain:
Dat kan in C# niet. Je kunt (bij mijn weten) een methode alleen aanroepen via een bepaalde interface (of het moet via een omweg met reflection kunnen, maar daar ga ik me al helemaal niet aan wagen).

@Mastermind:
Een IList<T> is niet te casten naar een IList. Althans, dat geeft hier een cast exception op. Dit had ik overigens al geprobeerd. Zie ook de start post.


Conclusie:

Ik ga voor List<T>, want blijkbaar is IList<T> geen abstractie die te sorteren is, maar List<T> wel. Iedereen bedankt sowieso en als iemand nog wat te melden heeft, dan graag.

Noushka's Magnificent Dream | Unity


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Het sorteren van een List<T> gaat overigens zo: (C# only)
// ascending
myList.Sort(delegate( T a, T b ) { return (a.FieldToSortOn.CompareTo( b.FieldToSortOn )); } );

// descending
myList.Sort(delegate( T a, T b ) { return -(a.FieldToSortOn.CompareTo( b.FieldToSortOn )); } );

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 29-11 15:35
Michali schreef op vrijdag 30 november 2007 @ 14:56:

@Mastermind:
Een IList<T> is niet te casten naar een IList. Althans, dat geeft hier een cast exception op. Dit had ik overigens al geprobeerd. Zie ook de start post.
Werkt hier wel hoor Copy/paste maar in je Visual Studio.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            IList<FieldEngine> iList = new List<FieldEngine>();
            FieldEngine f1 = new FieldEngine();
            f1.FieldName = "2";
            iList.Add(f1);
            FieldEngine f2 = new FieldEngine();
            f2.FieldName = "1";
            iList.Add(f2);
            iList = SortIList(iList); // Geeft gesorteerde IList
        }

        public class ToStringComparer : IComparer
        {
            public int Compare(object x, object y)
            {
                return ((FieldEngine)x).FieldName.ToString().CompareTo(((FieldEngine)y).FieldName.ToString());
            }
        }

        public IList<FieldEngine> SortIList(IList<FieldEngine> list)
        {
         
            ArrayList.Adapter((IList)list).Sort(new ToStringComparer());

            return list;
        }
    }

    public class FieldEngine
    {
        public FieldEngine() { }

        private string _fieldName;
        public string FieldName
        {
         get   {  return _fieldName;   }
         set   {  _fieldName = value;  }
        }
    }
    
}

  • Jeanpaul145
  • Registratie: Juli 2007
  • Laatst online: 15-07 14:52
Michali schreef op vrijdag 30 november 2007 @ 12:34:
Ik snap je punt wel, maar ik was gewoon benieuwd of IList<T> ook gemakkelijk te sorteren was.
Dit is het ook, als je genoeg van sorteeralgoritmen afweet ;)

:j


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:17
Zou je bij een sorteerbare type niet een IComparable<T> oid moeten pakken?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1