ฉันรู้ว่าต่อไปนี้เป็นกรณี ๆ ไป:
if (StringA == StringB) {
ดังนั้นมีผู้ประกอบการซึ่งจะเปรียบเทียบสองสายในลักษณะที่ไม่รู้สึก?
~=
กับขนาน==
เป็นรุ่นที่ไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก
ฉันรู้ว่าต่อไปนี้เป็นกรณี ๆ ไป:
if (StringA == StringB) {
ดังนั้นมีผู้ประกอบการซึ่งจะเปรียบเทียบสองสายในลักษณะที่ไม่รู้สึก?
~=
กับขนาน==
เป็นรุ่นที่ไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก
คำตอบ:
ลองสิ่งนี้:
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
if A$=B$ then goto 10
"
วิธีที่ดีที่สุดในการเปรียบเทียบ 2 สตริงโดยไม่สนใจขนาดตัวพิมพ์ใหญ่คือการใช้วิธีสตริง String.Equalsคงที่ระบุการเปรียบเทียบสตริงสตริงกรณีที่ไม่สนใจ นี่เป็นวิธีที่เร็วที่สุดเร็วกว่าการแปลงสตริงเป็นตัวพิมพ์เล็กหรือตัวใหญ่และเปรียบเทียบมันหลังจากนั้น
ฉันทดสอบประสิทธิภาพของทั้งสองวิธีและการเปรียบเทียบสตริงตัวพิมพ์เล็กและตัวพิมพ์เล็กนั้นเร็วกว่า 9 เท่า ! นอกจากนี้ยังมีความน่าเชื่อถือมากกว่าการแปลงสตริงเป็นตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่ (ดูปัญหาภาษาตุรกี i) ดังนั้นให้ใช้วิธีการString.Equalsเสมอเพื่อเปรียบเทียบสตริงเพื่อความเท่าเทียมกัน:
String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);
หากคุณต้องการทำการเปรียบเทียบสตริงเฉพาะวัฒนธรรมคุณสามารถใช้รหัสต่อไปนี้:
String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);
โปรดทราบว่าตัวอย่างที่สองใช้ตรรกะการเปรียบเทียบสตริงของวัฒนธรรมปัจจุบันซึ่งทำให้ช้ากว่าการเปรียบเทียบ "ลำดับกรณีที่ไม่สนใจ" ในตัวอย่างแรกดังนั้นหากคุณไม่ต้องการตรรกะการเปรียบเทียบสตริงเฉพาะวัฒนธรรมและคุณ หลังจากประสิทธิภาพสูงสุดให้ใช้การเปรียบเทียบ "ลำดับกรณีที่ไม่สนใจ"
ToLower
หรือToLowerInvariant
: พวกเขาสร้างหน่วยความจำเพียงเพื่อทำการเปรียบเทียบและพวกเขาอาจล้มเหลวในขณะที่ชุดอักขระใหม่จะถูกเพิ่มลงใน Unicode ToUpper
ล้มเหลวเนื่องจากตุรกี 'i' และอื่น ๆ ไม่มีเหตุผลใดที่ToLower
จะไม่ล้มเหลวในอนาคตด้วยเหตุผลที่คล้ายคลึงกัน
ToLower
หรือToLowerInvariant
วิธีการฉันแค่อยากจะแสดงให้เห็นว่ามีประสิทธิภาพมากขึ้นString.Equals
วิธีการคือ
มีคุณสมบัติจำนวนหนึ่งบนStringComparer
คลาสสแตติกที่ส่งคืนตัวเปรียบเทียบสำหรับชนิดของตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ที่คุณอาจต้องการ:
ตัวอย่างเช่นคุณสามารถโทร
StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)
หรือ
StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)
มันค่อนข้างสะอาดกว่าstring.Equals
หรือstring.Compare
โอเวอร์โหลดที่StringComparison
โต้แย้งกัน
System.Collections.CaseInsensitiveComparer
หรือ
System.StringComparer.OrdinalIgnoreCase
string.Equals(StringA, StringB, StringComparison.CurrentCultureIgnoreCase);
หรือ
if (StringA.Equals(StringB, StringComparison.CurrentCultureIgnoreCase)) {
แต่คุณต้องแน่ใจว่า StringA ไม่ใช่โมฆะ ดังนั้นอาจใช้ tu ดีกว่า:
string.Equals(StringA , StringB, StringComparison.CurrentCultureIgnoreCase);
ตามที่จอห์นแนะนำ
แก้ไข: แก้ไขข้อผิดพลาด
คุณสามารถใช้ได้
if (stringA.equals(StringB, StringComparison.CurrentCultureIgnoreCase))
ผู้ประกอบการ? ไม่ แต่ฉันคิดว่าคุณสามารถเปลี่ยนวัฒนธรรมของคุณเพื่อให้การเปรียบเทียบสตริงไม่ได้ตรงตามตัวพิมพ์ใหญ่ - เล็ก
// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo
ฉันมั่นใจว่ามันจะเปลี่ยนวิธีการเปรียบเทียบสตริงโดยตัวดำเนินการเท่ากับ
นี่เป็นแนวคิดที่จะทำให้ไวยากรณ์ง่ายขึ้น:
public class IgnoreCase
{
private readonly string _value;
public IgnoreCase(string s)
{
_value = s;
}
protected bool Equals(IgnoreCase other)
{
return this == other;
}
public override bool Equals(object obj)
{
return obj != null &&
(ReferenceEquals(this, obj) || (obj.GetType() == GetType() && this == (IgnoreCase) obj));
}
public override int GetHashCode()
{
return _value?.GetHashCode() ?? 0;
}
public static bool operator ==(IgnoreCase a, IgnoreCase b)
{
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
public static bool operator !=(IgnoreCase a, IgnoreCase b)
{
return !(a == b);
}
public static implicit operator string(IgnoreCase s)
{
return s._value;
}
public static implicit operator IgnoreCase(string s)
{
return new IgnoreCase(s);
}
}
ใช้งานได้เช่น:
Console.WriteLine((IgnoreCase) "a" == "b"); // false
Console.WriteLine((IgnoreCase) "abc" == "abC"); // true
Console.WriteLine((IgnoreCase) "Abc" == "aBc"); // true
Console.WriteLine((IgnoreCase) "ABC" == "ABC"); // true
IgnoreCase
vs IgnoreCaseString
) และคลุมเครือ (Java เลือกการชกมวย unboxing โดยปริยาย vs Java ดังนั้นฉันเชื่อว่าสิ่งนี้จะไม่ทำงานใน Java ด้วยการส่งกลับโดยนัยในสตริง) และสิ่งนี้จะสร้างโอเวอร์เฮดของหน่วยความจำของวัตถุใหม่ 2 ชิ้นโดยมีการเรียกใช้ทรีทรีสำหรับการเปรียบเทียบแต่ละครั้งจะกระโดดไปยังเมธอดซ้อนหลายแบบสำหรับกรณีการใช้งานที่แสดง ที่กล่าวมาสำหรับกรณีส่วนใหญ่ประสิทธิภาพอาจดีพอ
ฉันคุ้นเคยกับการพิมพ์ที่ส่วนท้ายของวิธีการเปรียบเทียบเหล่านี้: , StringComparison.
ดังนั้นฉันจึงขยาย
namespace System
{ public static class StringExtension
{
public static bool Equals(this string thisString, string compareString,
StringComparison stringComparison)
{
return string.Equals(thisString, compareString, stringComparison);
}
}
}
เพียงแค่ทราบว่าคุณจะต้องตรวจสอบ null thisString
ก่อนโทร ext
string.Compare(string1, string2, true)
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {
ผู้คนรายงาน ToUpperInvariant () เร็วกว่า ToLowerInvariant ()
อื่น ๆ คำตอบที่ถูกต้องทั้งหมดที่นี่ แต่อย่างใดมันต้องใช้เวลาในการพิมพ์และยังมีการใช้StringComparison.OrdinalIgnoreCase
String.Compare
ฉันเขียนรหัสวิธีการขยายสตริงอย่างง่ายซึ่งคุณสามารถระบุได้ว่าการเปรียบเทียบนั้นตรงตามตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กหรือใหญ่โดยใช้บูลีนหรือไม่ - ดูคำตอบต่อไปนี้: