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

[C#] Opvragen van alle beschikbare velden in een object

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

  • denyos
  • Registratie: Februari 2004
  • Laatst online: 08:08
Ik heb een functie gemaakt die een array van objecten sorteert op 1 van de velden(veld:voorbeeld) uit dit object.
Hiervoor haal ik voor ieder object de waarden uit het veld "voorbeeld", en indien deze nog niet in een tijdelijke arraylist voorkomt dan voegt ik deze waarden toe. Hierna sorteer ik deze ArrayList en vervolgens ga ik met deze ArrayList de array van objecten sorteren.
Tot zo ver geen enkel probleem. Het sorteren gaat prima, en het doet wat ik in eerste instantie wilde dat hij ging doen.

Maar toen had ik een kort overleg met een collega over deze methode, en hij was toevallig ook tegen een probleem zoals deze aangelopen, alleen wilt hij hem sorteren op een ander veld uit het object. Nu kan ik natuurlijk gewoon de functie kopieren met een andere naam, en vervolgens sorteren op een ander veld maar het zou mooier zijn als ik dit generiek zou kunnen maken.

Hiervoor lijkt het mij noodzakelijk om een veldnaam aan de functie mee te geven (gewoon een string), maar daar komt het probleem om de hoek kijken. Hoe krijg ik dit veld vervolgens uit mijn object. Hieronder een klein stukje voorbeeld code om 1 en ander duidelijker te maken.

code:
1
2
3
4
5
private void SorteerSample(string sorteerveld)
{
DemoObject demo = new DemoObject();
string gezochtewaarde = demo.[sorteerveld].ToString();
}


Ik heb hierbij geen flauw idee hoe dit heet wat ik wil, waardoor zoeken al een stukje lastiger wordt.
Wel heb ik gezocht naar manieren om in C# met een loop door alle velden van een object te lopen, maar dit heeft tot op heden geen succes gebracht.

Hopelijk kan iemand mij de juiste richting op slaan (of gewoon een duwtje in de juiste richting is ook goed).

Strava


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:59

Janoz

Moderator Devschuur®

!litemod

Toverwoord hier is 'reflection'. Bedenk echter wel dat het op dit soort manier dynamisch benaderen van objecten redelijk tricky en onveilig kan zijn.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 23:37

TeeDee

CQB 241

Reflection.

edit:
darn, Janoz.

[ Voor 57% gewijzigd door TeeDee op 23-01-2008 11:05 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


  • denyos
  • Registratie: Februari 2004
  • Laatst online: 08:08
Bedankt voor jullie snelle antwoord! Een snelle blik op Codeguru geeft het vermoede dat ik hier heel veel aan ga hebben.

Strava


  • whoami
  • Registratie: December 2000
  • Laatst online: 09:47
Met reflection is het idd mogelijk, maar bedenk ook wel dat reflection een impact heeft op je performance.

Als je echt nu weet op welke velden je mogelijks wilt sorteren (en het is een beperkte set velden), dan zou ik toch opteren om voor ieder veld waarop je mogelijk wilt sorteren, en andere comparer te maken.

https://fgheysels.github.io/


  • denyos
  • Registratie: Februari 2004
  • Laatst online: 08:08
De performance bij deze applicatie is niet erg belangrijk, maar het is inderdaad wel een puntje om bij stil te staan. Zeker als ik het op meer plaatsen ga gebruiken.

Strava


  • Ruudjah
  • Registratie: November 1999
  • Laatst online: 06-09 20:58

Ruudjah

2022

DIT BERICHT IS PREVENTIEF VERWIJDERD DOOR DE GEBRUIKER

[ Voor 90% gewijzigd door Ruudjah op 01-12-2009 22:21 ]

TweakBlog


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:59

Janoz

Moderator Devschuur®

!litemod

In deze situatie zou ik trouwens niet gebruik maken van reflection, sterker nog, voor deze toepassing zou ik het sterk afraden. Het is zoals ik en whoami al zeiden tricky, onveilig en inefficient.

Wat je beter kunt doen is een comperator schrijven. Wanneer je nu op een ander veld wilt sorteren geef je gewoon een andere comperator mee. In deze comperator implementeer je de daadwerkelijke vergelijkingen.

Ik zou het trouwens erg vreemd vinden wanneer dit niet een C# gefaciliteerd werd.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
Had er ook nog niet van gehoord, maar met een IComparer<T> werkt het ook wel heel fancy:
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
public class MyClass
{
    public string Name { get; set; }
    public int First { set; get; }
    public int Second { set; get; }

    public override string ToString()
    {
        return string.Format("{0}|{1}|{2}", Name, First, Second);
    }
}

public class FirstComparer : IComparer<MyClass>
{
    public int Compare(MyClass x, MyClass y)
    {
        return x.First - y.First;
    }
}

public class SecondComparer : IComparer<MyClass>
{
    public int Compare(MyClass x, MyClass y)
    {
        return x.Second - y.Second;
    }
}

static void Main(string[] args)
{
    MyClass[] a = new MyClass[]
    {
        new MyClass() { Name = "1st", First = 3, Second = 2 },
        new MyClass() { Name = "2nd", First = 2, Second = 1 },
        new MyClass() { Name = "3th", First = 1, Second = 3 }
    };

    Console.WriteLine("Original array:");
    Array.ForEach(a, Console.WriteLine);

    Console.WriteLine("Sorted on First field:");
    Array.Sort(a, new FirstComparer());
    Array.ForEach(a, Console.WriteLine);

    Console.WriteLine("Sorted on Second field:");
    Array.Sort(a, new SecondComparer());
    Array.ForEach(a, Console.WriteLine);
}

Original array:
1st|3|2
2nd|2|1
3th|1|3
Sorted on First field:
3th|1|3
2nd|2|1
1st|3|2
Sorted on Second field:
2nd|2|1
1st|3|2
3th|1|3

[ Voor 9% gewijzigd door riezebosch op 23-01-2008 15:42 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • whoami
  • Registratie: December 2000
  • Laatst online: 09:47
Janoz schreef op woensdag 23 januari 2008 @ 14:30:

Ik zou het trouwens erg vreemd vinden wanneer dit niet een C# gefaciliteerd werd.
Tuurlijk kent C# comparers. :)
Ik had er al op gealludeerd. :P

https://fgheysels.github.io/


  • Ruudjah
  • Registratie: November 1999
  • Laatst online: 06-09 20:58

Ruudjah

2022

DIT BERICHT IS PREVENTIEF VERWIJDERD DOOR DE GEBRUIKER

[ Voor 96% gewijzigd door Ruudjah op 01-12-2009 22:21 ]

TweakBlog


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
Zit trouwens nog wat te tweaken aan m'n voorbeeldje, maar kom nu wat dingen tegen die wél werken maar ik niet helemaal snap waarom. Dit werkt namelijk ook:
C#:
1
2
3
4
5
6
7
8
9
MyClass[] a = new MyClass[]
{
    new MyClass() { Name = "1st", First = 3, Second = 2 },
    new MyClass() { Name = "2nd", First = 2, Second = 1 },
    new MyClass() { Name = "3th", First = 1, Second = 3 }
};

Array.ForEach<MyClass>(a, delegate(MyClass p) { Console.WriteLine(p); });
Array.ForEach(a, Console.WriteLine);


Nu heb ik het typeinformatie van de generic eraf gehaald en de Console.WriteLine uit de delegate gehaald. Het laatste snap ik nog wel, blijkbaar voldoet WriteLine aan de signatuur van Action (toch?). Maar waarom ForEach ook zonder <> werkt kan ik niet helemaal bij.

[ Voor 4% gewijzigd door riezebosch op 23-01-2008 15:43 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • Ruudjah
  • Registratie: November 1999
  • Laatst online: 06-09 20:58

Ruudjah

2022

DIT BERICHT IS PREVENTIEF VERWIJDERD DOOR DE GEBRUIKER

[ Voor 94% gewijzigd door Ruudjah op 01-12-2009 22:21 ]

TweakBlog


  • HawVer
  • Registratie: Februari 2002
  • Laatst online: 17-11 22:54
Janoz schreef op woensdag 23 januari 2008 @ 14:30:
Het is zoals ik en whoami al zeiden tricky, onveilig en inefficient.
Hoezo is reflection tricky en onveilig? :? Meeste van de .net tools werken ook met reflection. De info die reflection gebruikt zit diep in .Net waar je dus wel degelijk op kunt vertrouwen.
Overigens heb je wel gelijk dat reflection niet de beste oplossingsstrategie is voor dit probleem.

http://hawvie.deviantart.com/


  • whoami
  • Registratie: December 2000
  • Laatst online: 09:47
Het gaat 'm er om dat je reflection niet voor gelijk wat moet toepassen.
Het laat je toe om private members te veranderen of te invoken bv.

https://fgheysels.github.io/


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
Ruudjah schreef op woensdag 23 januari 2008 @ 16:10:
Console.WriteLine() roept de ToString() methode aan van de instantie van de klasse. Aangezien ToString overerft van Object (waar alle C# lkassen van overerven), is in de eerste generic method call de <MyClass> niet nodig. Immers: in de tweede call naar Array.ForEach wordt een klasse van het type object gevraagd.
Maar ook dit werkt gewoon:
C#:
1
2
3
4
5
6
7
8
9
10
static void Main(string[] args)
{
    int[] a = new int[] { 1, 2, 3, 4 };
    Array.ForEach(a, foo);
}

static void foo(int i)
{
    Console.WriteLine(i);
}

Waarbij foo dus niet op een object uitgevoerd wordt. Misschien dat er nu impliciet dingen gedaan worden, maar ik zie niet echt de meerwaarde ervan om Array.ForEach<int>(...) te doen.

[ Voor 36% gewijzigd door riezebosch op 23-01-2008 17:16 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • EfBe
  • Registratie: Januari 2000
  • Niet online
riezebosch schreef op woensdag 23 januari 2008 @ 17:12:
[...]

Maar ook dit werkt gewoon:
C#:
1
2
3
4
5
6
7
8
9
10
static void Main(string[] args)
{
    int[] a = new int[] { 1, 2, 3, 4 };
    Array.ForEach(a, foo);
}

static void foo(int i)
{
    Console.WriteLine(i);
}

Waarbij foo dus niet op een object uitgevoerd wordt. Misschien dat er nu impliciet dingen gedaan worden, maar ik zie niet echt de meerwaarde ervan om Array.ForEach<int>(...) te doen.
In C# worden generic arguments van een method bepaalt mbv de parameters van de method.

Als ik heb
public void Foo<T>(T bar)
{
//...
}

en ik roep deze aan met:
Foo("lalala");

dan is T van het type string.

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


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
EfBe schreef op woensdag 23 januari 2008 @ 18:47:
[...]

In C# worden generic arguments van een method bepaalt mbv de parameters van de method.

Als ik heb
public void Foo<T>(T bar)
{
//...
}

en ik roep deze aan met:
Foo("lalala");

dan is T van het type string.
Aha, ik had al zo'n vermoeden. Het is dus ook niet nodig om dat dan nog expliciet aan te geven, hoewel het ook wel weer gewoon kan?

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • EfBe
  • Registratie: Januari 2000
  • Niet online
riezebosch schreef op woensdag 23 januari 2008 @ 23:18:
[...]

Aha, ik had al zo'n vermoeden. Het is dus ook niet nodig om dat dan nog expliciet aan te geven, hoewel het ook wel weer gewoon kan?
Correct :).Je MOET het aangeven wanneer de method geen parameter heeft, bv:
public T Foo<T>()
{
//
}

Als je dan doet:
string s = Foo();

dan werkt dat niet.

[ Voor 22% gewijzigd door EfBe op 24-01-2008 09:17 ]

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

Pagina: 1