it-swarm.com.de

Was ist der richtige Weg, um den Char ignorierenden Fall zu vergleichen?

Ich frage mich, auf welche Weise zwei Charaktere richtig miteinander verglichen werden können, wobei der Fall ignoriert wird, der für alle Kulturen gilt. Ist Comparer<char>.Default der beste Weg, zwei Zeichen zu testen, ohne dabei die Groß- und Kleinschreibung zu ignorieren? Funktioniert das für Ersatzpaare?

EDIT: Beispiel-IComparer<char>-Implementierung hinzugefügt

Wenn dies jemandem hilft, habe ich mich dazu entschieden

public class CaseInsensitiveCharComparer : IComparer<char> {
    private readonly System.Globalization.CultureInfo ci;
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {
        this.ci = ci;
    }
    public CaseInsensitiveCharComparer()
        : this(System.Globalization.CultureInfo.CurrentCulture) { }
    public int Compare(char x, char y) {
        return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);
    }
}

// Prints 3
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer()));
46
Brett Ryan

Es hängt davon ab, was Sie unter "Arbeit für alle Kulturen" verstehen. Möchten Sie, dass "ich" und "ich" auch in der Türkei gleich sind?

Du könntest benutzen:

bool equal = char.ToUpperInvariant(x) == char.ToUpperInvariant(y);

... aber ich bin nicht sicher, ob dies nach Ihrem Verständnis von "Werken" für alle Kulturen "funktioniert".

Natürlich können Sie beide Zeichen in Strings konvertieren und dann den gewünschten Vergleich der Strings durchführen. Etwas weniger effizient, bietet Ihnen jedoch alle im Rahmen verfügbaren Vergleiche:

bool equal = x.ToString().Equals(y.ToString(), 
                                 StringComparison.InvariantCultureIgnoreCase);

Für Ersatzpaare ist ein Comparer<char> sowieso nicht machbar, da Sie keine einzige char haben. Sie könnten jedoch einen Comparer<int> erstellen.

78
Jon Skeet

Verwenden der Standardkultur (dh nicht der Invariante): 

if (char.ToLower(ch1) == char.ToLower(ch2))
{  ....  }

Oder spezifizieren Sie eine Kultur:

CultureInfo myCulture = ...;
if (char.ToLower(ch1, myCulture) == char.ToLower(ch2, myCulture))
{  ....  }
13
Henk Holterman

So wie ich es verstehe, gibt es nicht wirklich einen Weg, "der für alle Kulturen funktioniert". Entweder möchten Sie Zeichen für eine Art interner, nicht für den Benutzer angezeigter Grund vergleichen (in diesem Fall sollten Sie InvariantCulture verwenden), oder Sie möchten die CurrentCulture des Benutzers verwenden. Wenn Sie die aktuelle Kultur des Benutzers verwenden, erhalten Sie natürlich unterschiedliche Ergebnisse in verschiedenen Gebietsschemas. Sie sind jedoch konsistent mit den Erwartungen Ihrer Benutzer in diesen Gebietsschemas.

Ohne mehr über WARUM zu wissen, warum Sie zwei Charaktere vergleichen, kann ich Ihnen nicht wirklich raten, welchen Sie verwenden sollten. 

2
Jon Grant

string.Compare ("string a", "STRING A", true)

Es wird für jede Saite funktionieren

1
Sergio

Was ich dachte, dass innerhalb der Laufzeit verfügbar sein würde, ist ungefähr wie folgt

public class CaseInsensitiveCharComparer : IComparer<char> {
    private readonly System.Globalization.CultureInfo ci;
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) {
        this.ci = ci;
    }
    public CaseInsensitiveCharComparer()
        : this(System.Globalization.CultureInfo.CurrentCulture) { }
    public int Compare(char x, char y) {
        return Char.ToUpper(x, ci) - Char.ToUpper(y, ci);
    }
}

// Prints 3
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer()));
0
Brett Ryan

Ich würde empfehlen, Großbuchstaben zu vergleichen, und wenn sie nicht übereinstimmen, dann Kleinbuchstaben vergleichen, nur für den Fall, dass sich die Großbuchstaben und die Kleinbuchstabenlogik des Gebietsschemas etwas anders verhalten.

Nachtrag

Zum Beispiel,

int CompareChar(char c1, char c2)
{
    int  dif;

    dif = char.ToUpper(c1) - char.ToUpper(c2);
    if (diff != 0)
        dif = char.ToLower(c1) - char.ToLower(c2);
    return dif;
}
0
David R Tribble

Du könntest es versuchen:

    class Test{
    static int Compare(char t, char p){
        return string.Compare(t.ToString(), p.ToString(), StringComparison.CurrentCultureIgnoreCase);
    }
}

Aber ich bezweifle, dass dies der "optimale" Weg ist, aber ich bin nicht in all den Fällen, die Sie überprüfen müssen ...

0
ahawker