[C#] Case insensitive Contains op ObjectCollection

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Oogst
  • Registratie: Juli 2001
  • Laatst online: 31-08 09:33
Ik wil graag case insensitive kijken of een element voorkomt in een ListBox en een ComboBox. Nou dacht ik in eerste instantie daarvoor gewoon StringComparison.OrdinalIgnoreCase toe te kunnen voegen aan de call naar Contains, dus zo:

code:
1
2
mijnListBox.Items.Contains(textBoxName.Text, StringComparison.OrdinalIgnoreCase)
mijnComboBox.Items.Contains(textBoxName.Text, StringComparison.OrdinalIgnoreCase)


Ondanks dat Linq aan Contains() toevoegt dat je er OrginalIgnoreCase op kunt gebruiken, accepteert ie dit niet, dus blijkbaar voegt Linq dat niet toe aan de Contains functie van deze specifieke datastructuur of zo? Ik ben een C++ programmeur, dus de details van dit soort dingen in C# zijn nog nieuw voor me.

Mijn volgende idee was dus om zelf een functie te schrijven die case insensitive checkt of een element in de lijsten zit. Dat krijg ik echter alleen werkend met twee losse functies voor ListBox en ComboBox:

code:
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
public static bool containsCaseInsensitive(ListBox.ObjectCollection collection, string text)
{
    //check all the elements in the collection
    foreach (string element in collection)
    {
        if (text.Equals(element, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }
    }

    //if we get here, then the element was not found
    return false;
}

public static bool containsCaseInsensitive(ComboBox.ObjectCollection collection, string text)
{
    //check all the elements in the collection
    foreach (string element in collection)
    {
        if (text.Equals(element, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }
    }

    //if we get here, then the element was not found
    return false;
}


Het lijkt me duidelijk dat zo dezelfde functie twee keer maken niet cool is. Ik dacht dus iets te kunnen doen met generics of met dat ze allebei overerven van IList of zo, maar dat krijg ik niet compilend. Deze twee werken bijvoorbeeld ook niet:

code:
1
2
public static bool containsCaseInsensitive<T>(IList<T> collection, string text)
public static bool containsCaseInsensitive<T>(T collection, string text)


Dus eigenlijk twee vragen:
1. Waarom werkt Contains op ListBox en ComboBox niet met StringComparison.OrdinalIgnoreCase?
2. Hoe kan ik voorkomen dat ik die functie twee keer moet copy-pasten met verschillende parameters?

Alvast bedankt! :)

Devblog / portfolio
Swords & Soldiers
Awesomenauts
Proun
Cello Fortress


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Listboxes/Comboboxes bevatten niet per-se strings maar objects (items is van type ObjectCollection) dus een StringComparison enum value meegeven zou raar zijn bij een Contains method. Wat je wel kunt doen (makkelijkst denk ik) is zoiets:
C#:
1
mijnListBox.Items.OfType<string>().Contains("appel", StringComparer.OrdinalIgnoreCase)

De OfType returned een collectie welke enkel strings bevat (in dit geval alle items dus) en daarna kun je wel gewoon Contains gebruiken zoals je dat wilde. Als je 100% zeker weet dat er alleen maar strings in de items collectie zitten kun je i.p.v. OfType<string> ook Cast<string> gebruiken; daarmee worden alle items naar string gecast.

[ Voor 58% gewijzigd door RobIII op 14-03-2012 14:53 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Oogst
  • Registratie: Juli 2001
  • Laatst online: 31-08 09:33
Hmm, die pikt ie ook niet, met hele mooie errors:
NewSettingForm.cs(91,13): error CS1928: 'System.Collections.Generic.IEnumerable<string>' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.Queryable.Contains<TSource>(System.Linq.IQueryable<TSource>, TSource, System.Collections.Generic.IEqualityComparer<TSource>)' has some invalid arguments

NewSettingForm.cs(91,13): error CS1929: Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable<string>' to 'System.Linq.IQueryable<string>'

NewSettingForm.cs(91,78): error CS1503: Argument 3: cannot convert from 'System.StringComparison' to 'System.Collections.Generic.IEqualityComparer<string>'

[ Voor 188% gewijzigd door Oogst op 14-03-2012 14:55 ]

Devblog / portfolio
Swords & Soldiers
Awesomenauts
Proun
Cello Fortress


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
De code die ik postte werkt bij mij. Dus ergens doe je iets raars :P
Afbeeldingslocatie: http://codinghorror.typepad.com/.a/6a0120a85dcdae970b0128776ff992970c-pi
Maarre, laat eens zien hoe je de listbox/combobox vult en de code die je nu gebruikt met die Contains()?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Oogst
  • Registratie: Juli 2001
  • Laatst online: 31-08 09:33
Hmm, interessent, benieuwd wat ik fout doe...

Dit is hoe ik hem aanroep:

code:
1
if (listBoxSetting.Items.OfType<string>().Contains("QQQ", StringComparison.OrdinalIgnoreCase))


Dit is hoe die listBoxSetting wordt gedeclareerd:

code:
1
private System.Windows.Forms.ListBox listBoxSetting;


En hier wordt er wat ingestopt:

code:
1
this.listBoxSetting.Items.AddRange(new object[] {"<Default>"});

Devblog / portfolio
Swords & Soldiers
Awesomenauts
Proun
Cello Fortress


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je gebruikt een StringComparison.OrdinalIgnoreCase enum; als je mijn code goed bekijkt zie je dat ik een (static) StringComparer class (instance) meegeef ;) Het duurde effe voor ik 't zag B) maar de foutmelding is duidelijk: hij verwacht een stringcomparer, geen stringcomparison enum value ;)

[ Voor 49% gewijzigd door RobIII op 14-03-2012 15:11 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • DarthDavy
  • Registratie: Januari 2007
  • Laatst online: 06-06 16:12

DarthDavy

Excellent!

Je steekt geen strings in je listbox, maar een lijst van objecten met één string.

code:
1
this.listBoxSetting.Items.Add("<Default>");


Zo kan je bereiken, wat je wil bereiken zonder zelf functies te gaan schrijven (niet nodig, .NET heeft voldoende string functies)
code:
1
comboBox1.Items.OfType<string>().Contains("", StringComparer.Create(CultureInfo.CurrentCulture, true));

Bier zonder alcohol is zoals een BH aan de wasdraad: het beste is eruit


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
DarthDavy schreef op woensdag 14 maart 2012 @ 15:12:
Je steekt geen strings in je listbox, maar een lijst van objecten met één string.
En dus? Dat is dus een lijst van strings.
Dit werkt net zo goed:
C#:
1
2
3
myListbox.Items.AddRange(new object[] { "AAA", "BBB", "CCC", "DDD" });
var f = myListbox.Items.Cast<string>().Contains("aaa", StringComparer.OrdinalIgnoreCase);
Trace.WriteLine(string.Format("Item found: {0}", f));

Item found: True
DarthDavy schreef op woensdag 14 maart 2012 @ 15:12:
code:
1
comboBox1.Items.OfType<string>().Contains("", StringComparer.Create(CultureInfo.CurrentCulture, true));
Ik prefereer de static instances van de StringComparers; niet zo lelijk als dat hele .Create(blatiebloe) gedoe :P

[ Voor 30% gewijzigd door RobIII op 14-03-2012 15:16 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Oogst
  • Registratie: Juli 2001
  • Laatst online: 31-08 09:33
Jups, dat fixt het, nu doet ie het! :) Het was inderdaad StringComparer ipv StringComparison.

Dank u!

Devblog / portfolio
Swords & Soldiers
Awesomenauts
Proun
Cello Fortress


Acties:
  • 0 Henk 'm!

  • DarthDavy
  • Registratie: Januari 2007
  • Laatst online: 06-06 16:12

DarthDavy

Excellent!

RobIII schreef op woensdag 14 maart 2012 @ 15:13:
[...]

En dus? Dat is dus een lijst van strings.
Jah, was in de war met de AddRange...

Bier zonder alcohol is zoals een BH aan de wasdraad: het beste is eruit

Pagina: 1