Bagaimana saya bisa melakukan perbandingan string case-insensitive?

217

Bagaimana saya bisa membuat garis di bawah ini tidak sensitif huruf?

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username == (string)drUser["Username"]) != -1);

Saya diberi beberapa saran sebelumnya hari ini yang menyarankan agar saya menggunakan:

x.Username.Equals((string)drUser["Username"], StringComparison.OrdinalIgnoreCase)));

masalahnya adalah saya tidak bisa mendapatkan ini berfungsi, saya sudah mencoba baris di bawah ini, ini mengkompilasi tetapi mengembalikan hasil yang salah, mengembalikan pengguna terdaftar sebagai pengguna tidak terdaftar dan tidak terdaftar sebagai terdaftar.

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username.Equals((string)drUser["Username"], 
                                 StringComparison.OrdinalIgnoreCase)));

Adakah yang bisa menunjukkan masalahnya?

Jamie
sumber
1
Tipe data apa yang seharusnya drUser["Enrolled"]? Itu terlihat seperti nilai boolean, tetapi FindIndex()mengembalikan indeks. Jika indeks pengguna itu adalah 0, maka itu akan mengembalikan 0, yang mungkin salah. Padahal, pada kenyataannya itu benar. The Exists()Metode mungkin lebih baik dalam hal ini.
drharris
Apakah Anda yakin tidak ada waktu pemformatan atau ruang ekstra di satu bidang yang tidak ada di bidang lain?
joshlrogers
1
Saya sarankan menggunakan RegistedUsers.Any () daripada FindIndex (dan test).
Marc

Jawaban:

405

Ini bukan praktik terbaik dalam .NET framework (4 & +) untuk memeriksa kesetaraan

String.Compare(x.Username, (string)drUser["Username"], 
                  StringComparison.OrdinalIgnoreCase) == 0

Gunakan yang berikut ini sebagai gantinya

String.Equals(x.Username, (string)drUser["Username"], 
                   StringComparison.OrdinalIgnoreCase) 

MSDN merekomendasikan:

  • Gunakan kelebihan dari metode String.Equals untuk menguji apakah dua string sama.
  • Gunakan metode String.Compare dan String.CompareTo untuk mengurutkan string, bukan untuk memeriksa kesetaraan .
samudra4dream
sumber
8
Anda harus menggunakan string.Compare, bukan String.Compare.
Fred
5
@Fred Saya setuju tetapi bisakah Anda memenuhi syarat alasannya?
Gusdor
22
@ Fred Saya berharap untuk alasan teknis daripada 'karena Stylecop mengatakan demikian'. Apakah saya melewatkan sesuatu?
Gusdor
12
tidak ada perbedaan string.compare dengan String.Compare, string sinonim kelas System.String. dan member Compare adalah metode ekstensi. @ Fred @Gusdor
Nuri YILMAZ
23
@Gdor stringadalah praktik yang lebih baik daripada Stringkarena merupakan kata kunci bahasa. Untuk satu, Stringbisa menjadi sesuatu selain System.String, sedangkan stringtidak bisa. Juga, stringlebih atau kurang dijamin ada di C #, sedangkan Stringsecara teknis bagian dari .NET daripada C #.
Dave Cousineau
36

Anda harus menggunakan String.Comparefungsi statis seperti berikut

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0
Oleg
sumber
6
Tidak, Anda harus menggunakan String.Equalsbukan String.Compare. Tidak perlu menghitung mana yang lebih besar, hanya saja mereka tidak sama.
ErikE
@ErikE: Saya heran, metode mana yang akan Anda rekomendasikan untuk digunakan dalam 6 tahun lagi :-)
Oleg
3
Saya tidak heran! Saya yakin saya akan merekomendasikan menggunakan kesetaraan ketika Anda ingin semantik kesetaraan, dan menggunakan membandingkan ketika Anda ingin perbandingan semantik. Apa yang begitu sulit tentang itu? IEquatabledan IComparableJANGAN melakukan hal yang sama, dan Anda dapat memiliki kelas yang mengimplementasikan satu tetapi di mana itu TIDAK masuk akal untuk mengimplementasikan yang lain. Misalnya, Anda dapat memesan sampel sensor berdasarkan waktu tanpa ada yang sama (IComparable). Dan, Anda dapat menunjukkan apakah semuanya sama (IEquatable) tetapi tidak masuk akal untuk memesannya (misalnya, nomor seri komputer).
ErikE
@ErikE: Anda tidak mengerti sudut pandang saya. Jawaban lama sesuai dengan waktu penulisan. Seseorang seharusnya tidak menyentuh jawaban lama. Memang benar tentang sebagian besar produk. Praktik terbaik atau pilihan terbaik dari sudut pandang kinerja dapat diubah beberapa kali kemudian. Saya merasa tidak masuk akal untuk membahas tentang jawaban lama.
Oleg
18
Saya minta maaf, saya menganggapnya sebagai kritik atas kebenaran komentar saya. Jika yang Anda katakan adalah bahwa Anda mengakui jawaban lama Anda mungkin bukan yang terbaik, baguslah! Namun, saya harus tidak setuju dengan Anda tentang jawaban lama. Jawaban lama yang memberikan informasi yang buruk harus dikomentari, harus dipilih, karena mereka masih memberi informasi kepada pembaca saat ini .
ErikE
27

Silakan gunakan ini untuk perbandingan:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
Gautam Kumar Sahu
sumber
10
Perlu diketahui manfaat dan perangkap menggunakan CurrentCultureIgnoreCase vs OrdinalIgnoreCase. Jika Anda tidak membutuhkan semantik perbandingan budaya, simpan beberapa kinerja dan gunakan perbandingan ordinal.
ErikE
7

Jawaban yang lain benar-benar valid di sini, tetapi entah bagaimana butuh waktu untuk mengetik StringComparison.OrdinalIgnoreCasedan juga menggunakan String.Compare.

Saya telah mengkodekan metode ekstensi String sederhana, di mana Anda dapat menentukan apakah perbandingan case-sensitive atau case-sensitive dengan boolean, melampirkan seluruh potongan kode di sini:

using System;

/// <summary>
/// String helpers.
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// Compares two strings, set ignoreCase to true to ignore case comparison ('A' == 'a')
    /// </summary>
    public static bool CompareTo(this string strA, string strB, bool ignoreCase)
    {
        return String.Compare(strA, strB, ignoreCase) == 0;
    }
}

Setelah itu seluruh perbandingan lebih pendek sekitar 10 karakter - bandingkan:

Sebelum menggunakan ekstensi String:

String.Compare(testFilename, testToStart,true) != 0

Setelah menggunakan ekstensi String:

testFilename.CompareTo(testToStart, true)
TarmoPikaro
sumber
2
Saya tidak setuju dengan penamaan, bandingkan adalah fungsi yang terkenal di perangkat lunak dev dan Anda telah mengubah apa yang dilakukannya. Saya pikir Anda harus mengembalikan int seperti membandingkan atau mengubah nama menjadi sesuatu yang lain, 'IsEqual' misalnya.
Fred
7

Anda dapat (meskipun bertentangan) memperluas System.Stringuntuk memberikan metode ekstensi perbandingan case-insensitive:

public static bool CIEquals(this String a, String b) {
    return a.Equals(b, StringComparison.CurrentCultureIgnoreCase);
}

dan gunakan seperti itu:

x.Username.CIEquals((string)drUser["Username"]);

C # memungkinkan Anda untuk membuat metode ekstensi yang dapat berfungsi sebagai suggar sintaks dalam proyek Anda, cukup berguna saya katakan.

Ini bukan jawabannya dan saya tahu pertanyaan ini sudah lama dan terpecahkan, saya hanya ingin menambahkan bit-bit ini.

Felype
sumber
3

Saya pikir Anda akan menemukan informasi lebih lanjut di tautan ini:

http://codeidol.com/community/dotnet/controlling-case-sensitivity-when-comparing-two-st/8873/

Gunakan metode Bandingkan statis pada kelas String untuk membandingkan dua string. Apakah perbandingannya case-insensitive ditentukan oleh parameter ketiga dari salah satu kelebihannya. Sebagai contoh:

string lowerCase = "abc";
string upperCase = "AbC";
int caseInsensitiveResult = string.Compare(lowerCase, upperCase,
  StringComparison.CurrentCultureIgnoreCase);
int caseSensitiveResult = string.Compare(lowerCase,
  StringComparison.CurrentCulture);

Nilai caseSensitiveResult adalah -1 (menunjukkan bahwa huruf kecil adalah "kurang dari" huruf besar) dan caseInsensitiveResult adalah nol (menunjukkan bahwa huruf kecil "sama dengan" huruf besar).

i_thamary
sumber
1

Saya ingin menulis metode ekstensi untuk EqualsIgnoreCase

public static class StringExtensions
{
    public static bool? EqualsIgnoreCase(this string strA, string strB)
    {
        return strA?.Equals(strB, StringComparison.CurrentCultureIgnoreCase);
    }
}
Ranga
sumber
-11

Anda selalu dapat menggunakan fungsi: .ToLower (); .ToUpper ();

konversikan string Anda dan kemudian membandingkannya ...

Semoga berhasil

pengguna3895427
sumber
Saya tidak berpikir ini akan menyelesaikan masalahnya. Juga tandai bahwa pertanyaan ini sudah berusia lebih dari 4 tahun.
Vojtěch Dohnal
7
Ini menciptakan string baru, jadi saya menganggap ini sangat tidak efisien. Karena untuk membuat string baru ini semua karakter akan diperiksa dan dikonversi ke case yang diinginkan, maka perbandingan harus memeriksa semua karakter lagi. Jadi ia menggunakan lebih banyak memori dan kekuatan pemrosesan.
Air2
5
Ini adalah praktik yang sangat buruk karena alokasi memori.
Thorbjørn Lindeijer
Tidak hanya alokasi memori yang tidak perlu dan tidak efisien; itu juga gagal tes Turki .
dmitry